AgentLayerdocs
Reference

Changelog

Pulled from the plugin's CHANGELOG.md, refreshed hourly. Each release carries the Upgrade block the upgrade skill reads.

All notable changes to agent-kevin are recorded here. The format follows Keep a Changelog, and the project aims to follow Semantic Versioning.

The version that matters is the one in .claude-plugin/plugin.json. /plugin update pulls new plugin code; it does not touch a consumer's HOME files (AGENTS.md, SOUL.md, settings, rules, …) or run bun install. The Upgrade block in each release below is the machine-actionable contract that /agent-kevin:upgrade reads to reconcile a HOME after a code update. Producers write these with /agent-kevin:release.

Upgrade-block format

Each release carries an ### Upgrade section. Every actionable line is a single backticked tag plus a human note:

- `<kind>: <severity>` — <note>
  • kinddeps · settings · template/<file> · file · script · manual
  • severityrequired (deps/script) · mandatory (auto-applied) · optional (the upgrade asks first, with a diff) · additive (copy if absent) · none

A script: <severity> line means the release ships a one-time migration at skills/upgrade/scripts/<version>.ts (named for this release). /agent-kevin:upgrade runs it via the run_upgrade MCP tool — outside the Bash sandbox, so it can touch deny-gated paths. The script is self-contained, idempotent, and prints a JSON report; it carries no permanent footprint in the server and may be pruned once the minimum supported baseline passes it (a script: whose file is absent is treated as already-applied). Use it for heavy data moves; use manual for steps a human must do by hand.

A code-only release writes a single line: None — code-only, no bun install or HOME changes.

/agent-kevin:upgrade collects every Upgrade block from a HOME's recorded baseline (<HOME>/.kevin/version.json) up to the installed version, coalesces them, backs up touched files to .kevin/updates/, auto-applies the mandatory/additive/deps actions, and prompts per optional one. The new template files are the source of truth for content; these tags only say which files changed and how aggressively to apply.

[0.4.5] - 2026-09-13

Added

  • pr-walkthrough: understand, present, and record your own PR. Author-side only, the counterpart of pr-review. Rebuilds the change hunk by hunk from the diff, the task, and the sessions that wrote it, classifies each hunk by how hard it is to defend, verifies build/lint/tests locally, then writes one glanceable side-screen doc: a two-minute standup script, the diff tour in scroll order, the questions reviewers will ask with receipts, and a scene-per-path recording runbook. Undefended hunks become gaps with an action, never a bluff. --rehearse runs an interview (the room's questions one screen at a time, its misconceptions as the wrong options, every miss corrected against the code); --check <video> verifies a finished recording covered every scene. Rides the GitHub pack; never posts. Writes reports/reviews/.
  • The Claude Code status line, rendered by the plugin. kevin statusline draws the footer from the status-line JSON: model, folder, and branch on line one; the context bar (shown from the first render), cost with the hourly rate, session time, and the Pro/Max rate-limit windows on line two. Init writes the statusLine entry into the home's project settings, upgrade re-points it whenever the plugin cache moves, and the plugin ships its own subagentStatusLine for the agent panel rows.
  • Codex footer and skills budget. codex_setup writes a [tui] status line (model with reasoning, directory, branch, approval mode, context used) and a [skills] budget of 10,000 tokens (the most Codex allows; its 2% default shaves the plugin's descriptions) into each home's .codex/config.toml, keeping an operator's own values.

Changed

  • The user-level Codex note now recommends the model context window, read from Codex's model catalog cache (~/.codex/models_cache.json) so the paste-ready pair matches the cap the operator's account actually has.
  • The operating manual template documents the reports/ tree: a Memory Routing row for the reporting skills and the directory layout under Knowledge Structure.
  • The dashboard cheatsheet gets a "Presenting or recording your own PR" row, report_write lists the new skill, the GitHub pack walk and "Where Your Code Lives" name it, pr-review treats a walkthrough report as the author's stated intent rather than a superseded review, and standup adds a prep line for each open PR of yours with no walkthrough yet.
  • The README's skill count reads 40.

Upgrade

  • template/AGENTS.md: mandatory — Memory Routing gains the reporting-skills row and Knowledge Structure gains the reports/ tree; "Where Your Code Lives" names pr-walkthrough.
  • template/USER.md: optional — the GitHub login: line names both PR skills (one clause).
  • manual: optional — the status line: upgrade writes statusLine into <HOME>/.claude/settings.json when absent and re-points it when it names a stale plugin path (an operator's own line is kept); nothing to do unless the report shows a permission-error fallback, then paste the printed entry. Shows on relaunch.
  • manual: optional — Codex homes: upgrade regenerates .codex/config.toml with the [tui] status line and [skills] budget (trust the hooks again via /hooks); the larger model context window is a user-level, machine-wide cost choice, so paste the pair from .kevin/updates/codex-user-config.md only if you want it.

[0.4.4] - 2026-09-12

Added

  • pr-review: adversarial pull-request review with no GitHub write access. Two modes, picked by who wrote the PR. Review mode (a teammate's PR) builds the "How it works" section first (diagram + walkthrough), fans out across seven lanes (correctness, domain invariants and authorization, security, regressions and blast radius, conventions, tests, PR hygiene), sends every candidate through an independent verifier that scores it, builds and tests the head in a throwaway operator-namespaced worktree, and hands back a report of paste-ready inline comments with committable suggestion blocks. Reply mode (your own PR) judges every review thread against the head code, applies the accurate fixes uncommitted, pushes back on the wrong ones with receipts, and drafts replies in PR scroll order. Flags: review / reply, --quick, --no-local, --repo. Rides the GitHub pack; never posts.
  • reviews report category. report_write accepts it, the dashboard orders and colors it, and the report scan picks it up, so review reports surface in SessionStart context.

Changed

  • The dashboard cheatsheet gets a "Reviewing a PR" row, the GitHub pack walk in configure-skills names the skill that rides it, and init's AGENT_REPORTS note lists reviews among the categories.

Upgrade

  • template/AGENTS.md: mandatory — "Where Your Code Lives" names the pr-review skill among the tasks that target the code path (one clause).
  • template/USER.md: optional — a GitHub login: line under "Where Things Live". The skill reads it to tell your PRs from teammates' and offers to fill it in on first use, so skipping this only means one extra question later.

[0.4.3] - 2026-09-10

Changed

  • The README is a landing page; the manual lives at dev.agentlayer.one/docs. Pitch, the loop, a quick start for both hosts, a section map into the docs site, and highlights, with the stale tool and skill counts corrected (56 tools, 38 skills). The docs site is host-neutral, serves llms.txt / llms-full.txt, and renders this changelog.

Fixed

  • Seed import refreshes the Codex rules. The Codex rules file is generated from the permissions.ask entries a seed import merges into, so the seed-import skill now calls codex_setup when a bundle added ask entries to a Codex-wired home (.codex/hooks.json present); before, those commands ran unprompted under Codex until the next upgrade. codex_setup is also classified as a core grant by seed_scan, so the export interview no longer offers it as a custom entry.

Upgrade

  • None — code-only, no bun install or HOME changes.

[0.4.2] - 2026-09-09

Added

  • The Codex wiring carries the home's posture, read from its Claude settings. The generator now writes a [permissions.kevin] profile into .codex/config.toml (extends :workspace, denies every read of .kevin/secrets/ and of any .env under a workspace root while the MCP server still reads them, keeps .git writable so commits stay routine, and lists the code path and permissions.additionalDirectories as workspace roots, and enables the network inside the sandbox, since an approved escalation does not lift a profile, verified on 0.153), .codex/rules/kevin.rules (one prefix_rule that prompts per Bash(…) entry in permissions.ask, the same gate Claude Code applies), a [shell_environment_policy] that hands the model's shell the home variables and the home's AGENT_* settings (never a key, token, or secret), and the policy keys default_permissions, approval_policy = "on-request", approvals_reviewer = "user" when the operator has not set them. Verified live in a fixture home: secrets refused by policy, commits inside the sandbox, a push stopped by the rule until the operator approves. The reviewer model (auto_review) stays opt-in: it denied a named push and a local commit on the same fixture.
  • codex_setup MCP tool. Init and upgrade generate the wiring through it, since a Codex session's sandbox keeps the workspace's .codex/ read-only to the model's shell; the server runs outside that sandbox. The shell path stays as the fallback.
  • A paste-ready note for the user level (skills/init/scripts/codex-user-config.ts), the Codex counterpart of the Claude auto-mode block: the keys Codex accepts only in ~/.codex/config.toml (analytics, feedback, telemetry exporters, terminal animation and alternate screen, update checks, the approval policy and reviewer, a reasoning effort mapped from the Claude effortLevel), plus, while the user config lacks them, a user-level permission profile built from the Claude user settings' Read(…) denies and a ~/.codex/rules/default.rules built from its ask list. Nothing in the note names an agent: it governs every Codex session that is not an agent home. The plugin never writes a user-level file; init and upgrade save the note to .kevin/updates/codex-user-config.md and quote it.
  • The home's profile fills whatever the user level does not. Claude's user-level Read(…) denies that the operator's user-level Codex profile does not already carry land in the home's profile, so a home is covered before the operator pastes anything and the user-level file stays theirs, the rule Claude homes follow for settings that exist in the user file.
  • The generator is agent-neutral: names, the env prefix, and the rules file come from the plugin manifest, so a sibling plugin ships it unchanged.

Changed

  • Init asks under Claude Code, every time, whether the home also runs Codex, instead of skipping the step when Codex went unmentioned.
  • The generator refuses a .codex/config.toml that still carries the legacy sandbox_mode or sandbox_workspace_write keys, naming them: Codex does not combine them with a profile.

Upgrade

  • settings: mandatory — add to permissions.allow: mcp__plugin_agent-kevin_kevin__codex_setup (the new always-on core tool init and upgrade call to write a home's Codex wiring from outside the shell sandbox).
  • manual: optional — Codex homes: run $upgrade (or /agent-kevin:upgrade) once; the wiring gains the permission profile, the rules file, and the shell env. The hook commands are unchanged, so no re-trust unless the report says hooks.changed: true. If the generator refuses because of legacy sandbox_mode keys, delete them from the home's .codex/config.toml and rerun. The profile replaces the sandbox the home ran under and an escalation prompt no longer lifts it: a directory the agent writes that is neither the home nor the code path goes into the Claude settings' permissions.additionalDirectories, then rerun. Then paste the user-level block the report points at (.kevin/updates/codex-user-config.md) into ~/.codex/config.toml; every line in it is optional. Claude Code-only homes have nothing to do.

[0.4.1] - 2026-09-07

Added

  • Codex CLI is a second host. A checkout installs as a Codex plugin (.codex-plugin/plugin.json, the same skills/) through its own developer marketplace (.agents/plugins/marketplace.json, named agentdev-kevin, like the embedded Claude one). Codex 0.153 accepts neither bundled hooks nor a bundled MCP server that can learn which home it serves, so both live per home, generated by skills/init/scripts/codex-setup.ts: .codex/hooks.json (a SessionStart context entry, SessionEnd and PreCompact captures, the same two moments Claude Code captures at, and the PreToolUse guard below) and a [mcp_servers.kevin] table in .codex/config.toml with AGENT_HOME set. The generator merges into existing files, replaces only Kevin's own entries, and validates the TOML before writing. init (Step 7c) and upgrade run it; the operator trusts the folder and the four hook entries via /hooks. The hook commands carry the home as a double-quoted --home= argument (bun "<plugin>/bin/kevin" session-start --hook-protocol=codex --home="<home>"), no env prefix, shaped to parse under sh and under the PowerShell Codex uses on Windows alike. Supported today: an existing home run from Codex ($upgrade from a Codex session writes the wiring). A fresh $init under Codex, the upgrade cycle across Codex plugin versions, and native Windows (where the skills are bash and Codex runs PowerShell) are not exercised yet. Known limits under Codex: skills that name ${CLAUDE_PLUGIN_ROOT} rely on the plugin-root line the SessionStart header carries (an instruction, not a variable); the session radar (where-am-i, list_sessions) reads Claude transcripts only; and nothing in Codex denies the model reading the runtime secrets store the way the Claude settings do. Parity for those is the next release's scope.
  • bin/kevin … --home=PATH pins the agent home from the command line, setting both AGENT_HOME and KEVIN_HOME so an inherited override cannot outrank it; the generated Codex MCP registration sets both the same way. It is how the Codex hooks name their home.
  • session-start --hook-protocol=codex prints the static stack (identity files, indexes, task board) ahead of the same dynamic lane Claude gets, as one payload; the hook is registered with additionalContextLimit: 0, since Codex otherwise truncates a hook's context at about 2,500 tokens. The payload's first line names the harness so skills can tell hosts apart.
  • session-capture --hook-protocol=codex (--format=codex) reads Codex's rollout JSONL: user and assistant turns only, with the injected AGENTS.md, environment block, and $skill expansions dropped.
  • upgrade starts with a registration preflight (skills/upgrade/scripts/registration-check.ts): it reads Claude Code's marketplace registry and installed plugins, the home's settings, and Codex's config.toml, and reports a checkout registered under a name its catalog no longer carries, a retired marketplace repo, or a stale Codex registration, each with the exact commands that fix it. The skill quotes them, flips the home's enabledPlugins and extraKnownMarketplaces keys itself, and repeats the commands in its report until a later run finds nothing to do.
  • A PreToolUse guard on shell commands (bin/kevin guard, wired in hooks/claude.json for Bash and as the fourth Codex hook entry). A cd in one shell command moves the session's cwd for every later one; a home-relative path such as projects/blog-dev/posts/… then lands in whatever repo the cwd drifted to. The guard blocks a command that would write under knowledge/, projects/, or reports/ relatively while the cwd is outside the home (and the cwd has no such tree of its own), telling the model the absolute path to use. Reads, quoted mentions, and heredoc bodies pass. A cd inside the same command is followed too, so cd <repo> && cat > projects/x is caught from the home; a cd to a value the shell computes leaves the cwd unknown, which allows. Verified on both hosts: Codex presents every shell command to hooks as tool name Bash with tool_input.command, and starts each one in the workspace, so the drift there is only the single-command form (its sandbox also denies writes outside the workspace).
  • Session block headers record the harness and model that produced the block (· claude: claude-fable-5-1, · codex: gpt-6-astra), scoped to the block's new turns.

Changed

  • Session block headers and raw/sessions/index.json are keyed by the full session id, not its first 8 characters: Codex's time-ordered UUIDv7 ids share a prefix within the same ~65 seconds, so a second session could resolve to the first one's cursor. Entries written under a short key fold onto the full id on that session's next capture, keeping first_seen, briefing, and block history.
  • The Claude manifest declares its hooks (hooks/claude.json, was hooks/hooks.json) and MCP server explicitly; the plugin-root .mcp.json is gone, since Codex auto-discovers both default locations. A Claude Code home keeps its three hooks and gains the PreToolUse guard above; nothing else about it moves.
  • The MCP server hydrates the home's .claude/settings*.json env on first import (Codex does not inject it); the CLI shares the loader. Anything already in the environment always wins.
  • release bumps both manifests; manifests.test.ts fails when they drift.
  • The Claude developer catalog (.claude-plugin/marketplace.json, agentdev-kevin) is committed, as the Codex one already was, so a plain clone registers on both hosts.
  • The public marketplace is AgentLayer1/agentlayer-agent-marketplace, serving Claude Code (.claude-plugin/marketplace.json) and Codex (.agents/plugins/marketplace.json) from one repo. Its name is still agentlayer and the plugin id is still agent-kevin@agentlayer; the old agentlayer-claude-marketplace repo keeps working until it is retired.
  • Every disable-model-invocation skill opens with a one-line operator-only guard: Codex lists every plugin skill to the model and ignores that field, so without it the model could run init, release, or rename-agent on its own there. Inert under Claude Code, where the frontmatter already gates them.
  • The sync's brain commit sweeps .codex/ with the rest of the home's state, so the Codex wiring is committed instead of reported as left uncommitted on every run.
  • README, templates/AGENTS.md, and the init skill name the plugin manifest as where the bundled kevin server and the Claude hooks are registered.

Fixed

  • A turn truncated (or pasted) inside a three-backtick code fence left the fence open in the day file, rendering every later block as code; the capture formatter now closes it before the truncation marker (longer and tilde fences are not counted).
  • A capture that cannot take the capture lock in time no longer proceeds unlocked or dies to Codex's 3-second SessionEnd limit: it is queued in the runtime dir and the next capture, or the next session start, drains it. A legacy 8-character index key is now persisted onto the full id even when the capture finds no new turns.
  • The Codex session start delivers the identity files even when the dynamic lane fails to assemble (a marker line takes the lane's place), matching Claude Code's containment.

Upgrade

  • manual: optional — the marketplace moved to AgentLayer1/agentlayer-agent-marketplace (Claude Code and Codex from one repo). Registered from the old agentlayer-claude-marketplace? Run /plugin marketplace add github:AgentLayer1/agentlayer-agent-marketplace then /plugin install agent-kevin@agentlayer once: both repos carry the name agentlayer, so the new one replaces the old, the plugin id is unchanged, and nothing in your home changes.
  • manual: mandatory — a local clone registered under any name other than agentdev-kevin (a pre-0.4.1 directory install was registered as agentlayer) loads no plugin next session, because the clone's catalog is now named agentdev-kevin. Re-register it: /plugin marketplace remove <old name> (this uninstalls the plugin it brought), /plugin marketplace add <clone path>, /plugin install agent-kevin@agentdev-kevin. The upgrade's preflight prints these three lines with your paths and renames the home's enabledPlugins and extraKnownMarketplaces keys itself. Clones already registered as agentdev-kevin have nothing to do. Under Codex the plugin is a cache copy either way: codex plugin marketplace upgrade agentlayer then codex plugin add agent-kevin@agentlayer for the marketplace, or codex plugin remove and add of agent-kevin@agentdev-kevin for a clone.
  • template/AGENTS.md: optional — the tree-diagram comment on .mcp.json now says the bundled kevin server is registered in the plugin manifest (one comment line; declining loses nothing).
  • manual: optional — Codex: this upgrade asks once whether the home also runs Codex and, on yes, writes .codex/hooks.json and the [mcp_servers.kevin] table in .codex/config.toml. Then install the plugin in Codex if you have not (codex plugin marketplace add <checkout or marketplace>, codex plugin add agent-kevin@<marketplace>), launch codex from the home, trust the folder when asked, and trust the four Kevin entries via /hooks. A Codex-only home gets the same wiring from $upgrade run inside Codex. Claude Code-only homes answer no and have nothing to do.

[0.4.0] - 2026-09-06

Added

  • AGENTS.md is the operating manual. The agent home's manual is now a harness-neutral AGENTS.md at the root, read natively by Codex and every other AGENTS.md-aware CLI. Claude Code, which does not read AGENTS.md, reaches it through a new .claude/CLAUDE.md bridge: @-imports for the manual, the identity stack (SOUL, IDENTITY, USER) and the indexes, plus the few rules that apply only under Claude Code (plan mode, the auto-memory override, hook-driven capture). One manual at the root, no per-harness copies. templates/AGENTS.md is the manual; templates/CLAUDE.md is now the bridge.
  • 0.4.0 migration (skills/upgrade/scripts/0.4.0.ts): builds AGENTS.md from the legacy root CLAUDE.md (or CLAUDE.local.md): template preamble, sections carried verbatim, operator preamble kept, operator-added @-imports re-rooted into the bridge. Writes the bridge, retargets markdown links to the moved file, then removes the legacy file. Backs up every touched file to .kevin/updates/0.4.0-manual-<stamp>/, rolls back every write of the run on any verification failure, keeps CRLF line endings, idempotent.
  • ping reports the plugin version the server process loaded, so /agent-kevin:upgrade can detect a server older than the code on disk and stop before a migration silently reads as already applied.
  • The recommended auto-mode block is generated, not transcribed. skills/init/scripts/automode-block.ts renders it from the init skill's source of truth with the home's path substituted, checks the operator's user-global copy rule by rule (exact text, matched by rule name; environment is never compared), and writes a readable note with the changed sentences and paste-ready replacement entries to .kevin/updates/automode-block.md. init prints it at the end of onboarding; upgrade re-checks it every run. Print-only, as before: the plugin never writes ~/.claude/settings.json.
  • Session start flags a broken manual layout. When AGENTS.md exists but the .claude/CLAUDE.md bridge is missing, or a pre-0.4.0 root CLAUDE.md still sits beside AGENTS.md, the banner says so every session until /agent-kevin:upgrade fixes it — the two states in which Claude Code would load nothing or load the manual twice.

Changed

  • init writes AGENTS.md and the .claude/CLAUDE.md bridge. A project's own AGENTS.md at the home root gets the manual appended; a root CLAUDE.md is no longer a collision, and CLAUDE.local.md as the manual's alternate location retires.
  • upgrade maps both templates to their new homes (AGENTS.md, .claude/CLAUDE.md), runs the 0.4.0 migration before any template merge, refuses to proceed when the running server is older than the installed code, surfaces a user-global auto-mode block that predates AGENTS.md with paste-ready replacements, and no longer offers a seed template over a concept article the knowledge compile has taken over.
  • The server resolves the manual wherever a home currently keeps it (AGENTS.md, the legacy root CLAUDE.md, or CLAUDE.local.md), so compile, seed import, and the session-start placeholder scan keep working between a plugin update and the home's upgrade.
  • Seed format: the operating-manual overlay travels as AGENTS.md only. Bundles exported before 0.4.0 carry it as CLAUDE.md and are rejected by import; re-export them from a 0.4.0 plugin. Importing into a home not yet on the 0.4.0 layout still appends the overlay to its legacy manual.
  • The status collector reads the @-import chain from the bridge and labels imports HOME-relative in the dashboard; rename-agent sweeps the bridge despite the dot-directory exclusion; seed-export, release, self-review, sync, configure-skills, setup-worktree, and the project skills name the new files. README and the printed auto-mode block follow: the Agent Knowledge Base allow and the Identity File Replacement soft-deny now name AGENTS.md.

Upgrade

  • manual: nonerestart Claude Code after /plugin update, before running this upgrade. The MCP server changed; upgrade now compares ping's version with the installed code and stops on a stale server instead of treating the migration as already applied.
  • script: required — run skills/upgrade/scripts/0.4.0.ts via run_upgrade. Moves the manual from the root CLAUDE.md (or CLAUDE.local.md) to AGENTS.md and writes the .claude/CLAUDE.md bridge; retargets markdown links to the moved file; removes the legacy file. Backs up to .kevin/updates/0.4.0-manual-<stamp>/, rolls back on any verification failure, idempotent. Runs before any template merge.
  • template/AGENTS.md: mandatory — the operating manual. Claude Code-only mechanics (@-import context loading, the auto-memory override, the plan-mode rule, the hook capture note) moved out to the bridge; section text is otherwise carried from the previous CLAUDE.md template.
  • template/CLAUDE.md: mandatory — new file at .claude/CLAUDE.md (the Claude Code bridge). The migration writes it from this same template, so on a freshly migrated home this merge is a no-op; its @-import lines sit in the preamble, which section merges never touch.
  • template/knowledge/concepts/self-evolution-loop.md: optional — two CLAUDE.mdAGENTS.md mentions (the prompt-evolution paragraph and the guardrails table).
  • manual: optional — if you pasted the printed auto-mode block into ~/.claude/settings.json, two of its rules changed: Agent Knowledge Base (allow) and Identity File Replacement (soft-deny) now name AGENTS.md. The upgrade checks your copy, prints the changed sentences and the exact replacement entries, and writes the same as a note to .kevin/updates/automode-block.md; paste each over the entry with the same name. Until refreshed, auto mode classifies every write to AGENTS.md (template merges, seed-import appends) as Instruction Poisoning and may prompt or block.
  • manual: none — the migration retargets markdown links to the moved file and the one template sentence in USER.md that named it; every other mention of CLAUDE.md in operator-authored files is left as history. On the first session after upgrading, run /context and confirm .claude/CLAUDE.md lists its seven imports and no root CLAUDE.md remains.

[0.3.33] - 2026-09-05

Fixed

  • Session radar now works on Windows. The default scope for where-am-i, find-session, and standup was assembled in the shell from $PWD, which Git Bash hands over in POSIX form (/c/Users/...) — the script then resolved it against the wrong drive and the radar came back empty. Both scripts (list_sessions.ts, find_session.ts) now build the default themselves from process.cwd() plus the KEVIN_HOME/AGENT_HOME and KEVIN_CODE_PATH/AGENT_CODE_PATH env vars, which reach a native process in native form. --scope still overrides.

Changed

  • The three skills that call the radar (where-am-i, find-session, standup) drop their shell scope preamble and just run the script; --scope is now an override, not a required argument.

Upgrade

  • None — code-only, no bun install or HOME changes.

[0.3.32] - 2026-09-01

Changed

  • Seed manual overlay now targets CLAUDE.md, append-only and idempotent. CLAUDE.local.md was the wrong destination — in this plugin it is the operating manual's alternate location for the init-collision case and compile reads it with priority, so a seeded overlay there would shadow the real manual. The seed format now allows the CLAUDE.md path and refuses CLAUDE.local.md; import appends the overlay section to the scaffolded manual (never replaces, never conflicts) and skips it when the identical section is already present, making re-import a full no-op.
  • /agent-kevin:seed-import now offers to render a seeded roadmap draft (knowledge/concepts/roadmap-draft.md) via the roadmap skill.

Upgrade

  • None — code-only, no bun install or HOME changes.

[0.3.31] - 2026-08-31

Added

  • Seed bundles: hand your agent to a teammate. A one-shot export/import so an operator who has shaped their agent (renamed it, grown project knowledge, wired up custom skills and MCP servers) can give a teammate a starting point, while the teammate's memory, sessions, and credentials stay entirely their own. Two skills: /agent-kevin:seed-export runs a two-stage flow — an interview that builds the manifest (scope: whole agent / project slice with wikilink-driven concept discovery / identity only; identity; knowledge + surfaces; local setup beyond the scaffold; an optional CLAUDE.local.md overlay of curated operating-manual sections), then a per-file review gate over the actual bytes (approve / edit / exclude, scrub client names and personal paths — no approval, no bundle). /agent-kevin:seed-import overlays a bundle onto an initialized home with fork semantics: dry-run plan first, conflicts confirmed before overwriting, and it ends with the credential checklist the operator fills in their editor. Three MCP tools back them (seed_scan, seed_export, seed_import — the import runs outside the Bash sandbox so it can merge settings.json / .mcp.json and ensure the secrets store), plus a kevin seed CLI group for terminal use.
  • The bundle format (formatVersion 1) is a plain zip: manifest.json + payload files under seed-allowed roots only (identity files, knowledge/concepts/, projects/<slug>/{README.md,roadmap.html}, .claude/{skills,rules,assets}/, root roadmap.html, CLAUDE.local.md). Setup travels as manifest fields — permission entries, MCP server entries, and credential key names — never values; the import plants empty placeholders and reports what to fill. Import verifies payload hashes and path containment before any write, refuses symlink payloads, and never clobbers existing MCP server names; credential-shaped keys can't ride the settings-env field on either side. The format accepts a minimal producer (manifest + identity files, generated anywhere), so bundles don't have to come from a home.

Changed

  • /agent-kevin:init can start from a seed. New Step 1c asks whether a seed bundle from a teammate exists; when the bundle carries identity, the persona steps take defaults instead of interviewing for prose the seed will overwrite (operator-facts steps always run in full), and after the scaffold init delegates to the seed-import flow automatically.
  • README: new "Seed a teammate's agent from yours" use case, skills-table and CLI-table rows, and the MCP tool listing now counts 55 with the Seed group.

Upgrade

  • settings: mandatory — add to permissions.allow: mcp__plugin_agent-kevin_kevin__seed_scan, mcp__plugin_agent-kevin_kevin__seed_export, Skill(agent-kevin:seed-export), Skill(agent-kevin:seed-import); and add to permissions.ask: mcp__plugin_agent-kevin_kevin__seed_import (it overwrites identity files and merges permissions/MCP registrations from a foreign bundle, so it always confirms — same reasoning as curl_run).

[0.3.30] - 2026-08-25

Fixed

  • A planted data dir can no longer claim a directory as the agent home. Before v0.3.28 the logger scaffolded <cwd-fallback-home>/.kevin/logs/ just to record that session capture was skipping there, leaving bare .kevin/ dirs in trees that were never homes; v0.3.28's marker move from SOUL.md to the data dir then armed those plants — the next session-end inside such a tree resolved it as the home and captured sessions into <tree>/knowledge/, lost to the brain. The home marker is now a state file only the agent's own flows write — .kevin/version.json (init/upgrade) or .kevin/knowledge.json (compile) — named once as HOME_MARKER_FILES so isAgentHome, the logger's file-output gate, and the test preload can't drift. Both files are git-tracked in a brain repo, so a fresh clone still resolves. The logger's gate also honors the runtime-dir migration window now, and the stranded-home messages stop prescribing mkdir -p (which no longer repairs anything) in favor of restoring the two state files. Regression tests pin the incident shape: a data dir holding only logs/ neither anchors the walk-up nor re-arms file logging.

Upgrade

  • None — code-only, no bun install or HOME changes.

[0.3.29] - 2026-08-20

Added

  • Outbound checkpoint that survives auto mode. Init now writes a baseline permissions.ask into project settings — git push, gh pr create/merge, gh release create, and the curl_run MCP tool always stop for a human, in every permission mode. Since Claude Code v2.1.228, eligible sessions start in auto mode, where a classifier model approves actions instead of prompting; ask rules are the one tier the classifier cannot approve past, which makes them the durable form of "nothing leaves this machine without a human". The list is deliberately short: prompt volume is what trains operators to blind-click.
  • Printed auto-mode guidance for the operator's user settings. Kevin's memory lives in knowledge/, not the path auto mode's built-in memory exemption covers, so on shipped defaults the classifier can read a compile or memory write as Instruction Poisoning: the agent's core loop flagged as an attack. Init's summary now prints a copy-paste block for ~/.claude/settings.json carrying an explicit permissions.defaultMode: "auto", environment entries (an Agent homes: anchor with the home's real path interpolated at print time, plus an outbound-posture line), and two classifier allow sentences that treat the home's knowledge tree the way the built-in exceptions treat Claude's own memory directory. Every rule keys off that environment entry, so none of them depend on the classifier inferring which directory is an agent home, and the knowledge-base exception self-scopes to the home the session started in: an operator running two agents never grants one blanket rights over the other's identity files. The exemption names all three rules the built-in Memory Directory exception clears (Instruction Poisoning, Self-Modification, and Irreversible Local Destruction, the last being what would otherwise flag the compile loop's whole-article rewrites), and it is conditioned up front on content that neither changes permissions or auto-mode behaviour, fabricates consent, nor steers a future session toward a blocked action. .claude/, cross-home writes, content leaving the home, and directory-level deletion stay outside it. Print-only: Kevin never writes user-global settings.
  • Three classifier soft-denies ship in the same block, because excluding something from an allow rule blocks nothing on its own: the classifier's default is ALLOW, so anything the allow rules decline to cover needs a deny to actually stop it. Agent Home Outbound Push covers pushes, PR creation and merges, and release publication from any agent-home session, and declares the built-in Git Push Destination exception inapplicable there; explicit user intent clears it, so naming the action and its destination is enough. Treat that one as defense in depth rather than the wall: a deny-side rule overriding a mandatory built-in exception is a precedence conflict the classifier resolves on its own, which is why the project permissions.ask list above stays the primary gate. Identity File Replacement catches what would otherwise be a git-recoverable overwrite matching no built-in rule: replacing, deleting, moving, or renaming an identity file, or editing away more than a small part of one. Cross-Agent Home Write stops a session in one agent home writing into another, however small the edit, since each agent's brain is read back as instructions by that agent's own future sessions. Mirroring between the agents' plugin repositories is untouched: those are code repositories, not homes.

Changed

  • Upgrade gains two every-run invariants (not gated on this entry, so homes that skip releases still converge): union any missing baseline permissions.ask entries into project settings (fail-soft: when the operator's sandbox protects settings.json from agent writes, surface the exact JSON as a manual: note instead), and print the user-global auto-mode block when ~/.claude/settings.json has no defaultMode — the operator profile that reports permission-prompt fatigue. Silent when the operator has made any explicit mode choice.
  • Init documents that CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC=1 (Kevin's own gap-filled quality default) disables feature-flag fetching and with it Claude Code's built-in auto-mode default — sessions silently start Manual with nothing on screen saying why. The explicit defaultMode line in the printed block is the fix; dropping the traffic kill is not required.
  • The upgrade skill is model-invocable. A plain "upgrade kevin" or "apply the update" now reaches it — the operator doesn't have to know /agent-kevin:upgrade. No settings action: Skill(agent-kevin:upgrade) was already in the canonical grant list (kept latent so the slash form never prompted). Sync still surfaces the slash command instead of invoking it — upgrade chains sync at the end, so the reverse would recurse.

Fixed

  • Stray curl_run allow grants are retired. curl_run is the one sanctioned request-execution path in the api-collections skill and was never meant to be pre-granted — the whole point is that it always prompts. Some homes carry it in permissions.allow from earlier scaffolds or pack walks. The new ask entry outranks allow, so the gate holds either way, but the leftover grant is dead weight that misstates the home's audit trail (settings.json should read as an accurate record of what auto-approves). The upgrade offers the removal.

Upgrade

  • settings: mandatory — union the baseline permissions.ask list into project settings (outbound gates: push / PR create + merge / release / curl_run). The init skill's Step 7 list is the source of truth; applied by the upgrade's built-in invariant, so this line is documentation of what happened, not a separate action.
  • settings: optional — remove mcp__plugin_agent-kevin_kevin__curl_run from permissions.allow when present: superseded by the ask entry above and contrary to the never-pre-granted doctrine. Removal, so ask first with the diff; skip silently when absent.
  • manual: optional — paste the printed auto-mode block (permissions.defaultMode, the Agent homes: environment entry, two classifier allow sentences, two soft-denies) into ~/.claude/settings.json, then restart sessions and verify the mode indicator says Auto. Keep $defaults in every array you set: omitting it replaces that whole default list, discarding built-in rules. Review the result with claude auto-mode critique, run from outside the agent home when that home sets CLAUDE_CODE_OAUTH_TOKEN (a per-agent token shadows the credential the subcommand needs, and the failure reads as an unrelated auth error). Reversible with claude auto-mode reset. Tradeoff stated in the printed note: the knowledge-tree exception lowers the classifier's Instruction Poisoning guard for the agent's own memory paths.

[0.3.28] - 2026-08-20

Added

  • standup skill — your update in the three parts a standup actually has: what you did in the last 24h (merged PRs, prod actions run by hand, investigations that left no commit, tasks filed), what you're picking up next, and what's blocked with a named owner. Derived from git, PRs, session transcripts and the task board rather than asked for. Crosses the day boundary a standup does, flags older work a skipped run may have left unsaid, and stays glanceable while you're presenting. /agent-kevin:standup 48 widens the window.
  • find-session skill — locate a past session by what it worked on (a branch, a PR number, a worktree, a bug, a task id) and get its resume command back. Content search over all transcript history, ranked by did-the-work signals rather than hit count, so the session that merely mentioned a thing doesn't outrank the one that fixed it. The companion to where-am-i: that one answers when, this one what.
  • README: Running homes on different Claude accountsCLAUDE_CODE_OAUTH_TOKEN per home outranks the single /login slot, so two homes can bill two subscriptions at once. Covers minting with claude setup-token, why the token is the one credential that belongs in settings.local.json, and the five gotchas (switch /login between mints, restart to pick up the env block, launch from the home root, nothing higher-precedence shadowing it, verify with /status + /usage).

Changed

  • Sync's briefing auto-select is catch-up-aware. It used to read the clock alone, so a morning you never briefed silently became an evening brief at 3pm. Now it checks whether a morning brief actually ran today: none yet and it's 3am–9pm → a catch-up morning (even at 5pm); already ran, or past 9pm → evening. The header says which was picked and why.
  • where-am-i's description now points at find-session for content-shaped asks, so "which session was fixing X" routes to the right skill.

Fixed

  • The session radar no longer trusts file mtimes for recency. Claude Code touches open sessions' transcripts while they sit idle, so every live session read as "now" and a bulk touch (a git checkout, a backfill) could rank a stale session as the freshest. minutes_ago and the ordering now come from the transcript's last embedded record.

Removed

  • permission-check skill, and the permissions report category it was the only producer for — gone from the report_write enum, the dashboard's filter chips, and the orphan-file sweep. A home that already holds reports/permissions/ files keeps them on disk and still lists any that made it into reports/index.md; they just lose their filter chip.

Upgrade

  • settings: mandatory — add to permissions.allow: Skill(agent-kevin:find-session), Skill(agent-kevin:standup). Both are model-invocable; without the grants Kevin raises a confirm prompt every time it fires them.
  • settings: optionalSkill(agent-kevin:permission-check) is now a dead grant and can be dropped from permissions.allow. Harmless if left.

[0.3.27] - 2026-08-17

Added

  • A roadmap is a convention now, not config. roadmap.html lives at the root of whatever it covers: the HOME root for your north star, projects/<slug>/roadmap.html for a project's own plan. The dashboard discovers both without registration — the north star leads the sidebar's Surfaces group, and a project that keeps one gets a 🧭 row on its card. Only the north star is promoted to the sidebar; a project's roadmap lives on that project's card, so the sidebar doesn't grow a row per project.
  • create-project points new projects at the convention (and says not to scaffold an empty roadmap); roadmap offers the project-root path instead of a nested references/ location and reminds you to list it in the README's ## Structure.

Changed

  • Flywheel is framed by the roadmap. It reads the north star's ROADMAP object while orienting and uses it to break ties between equally urgent tasks, reads a project's own before deciding what to advance, and reconciles milestone statuses its work actually moved. Status-value edits only, evidence-backed — structural changes and drift go to the operator with /agent-kevin:roadmap, never a regeneration. sync's quick form carries the same two steps, since that's the path most flywheel runs take.

Fixed

  • README's MCP tool count was stale in two places (47 in the tool table, 48 in the sample session banner; actual: 52), and list_worktrees was missing from the Worktree group.
  • The sidebar's health and upgrade badges ran past the edge of the fixed-width sidebar once the issue list grew past a couple of signals. They wrap now — between whole signals, never mid-signal or onto a line-leading · — at the same font size, in the same sidebar width.

Upgrade

  • manual: optional — only if you keep a project roadmap at the old nested path projects/<slug>/references/roadmap.html: move it to projects/<slug>/roadmap.html so the dashboard finds it, and add a line for it in that project README's ## Structure. Otherwise nothing — code-only, no bun install, no HOME changes.

[0.3.26] - 2026-08-13

Added

  • Name your agent something other than Kevin. The display name and the plugin namespace were the same string, so the only way to run an agent called anything else was to fork and give up clean updates. They're now separate: the name is data in IDENTITY.md, the namespace (/agent-kevin:, KEVIN_*, .kevin/, MCP tool names) stays in the manifest. init asks for a name, emoji and avatar up front; the session banner, the TASKS.md header and the knowledge-compile prompts all render it, so compiled memory speaks about the agent you actually named.
  • rename-agent — rename an existing home. Rewrites the persona fields, swaps the avatar, and sweeps the prose across SOUL.md / CLAUDE.md / USER.md / knowledge / projects, leaving the plumbing alone. It refuses to touch Kevin sitting against a / or \, so a home at ~/Documents/Agents/Kevin keeps every path reference intact. Double-gated on purpose: disable-model-invocation, so it only runs from /agent-kevin:rename-agent and never fires on its own, and deliberately left out of the permission grants, so even that raises a confirm prompt. It rewrites the whole brain in one pass; both gates are intentional.
  • Unresolved scaffold placeholders are surfaced every session. init and upgrade substitute {{TOKEN}} and both check their own work, but those checks are skill instructions. SessionStart now scans the identity files and reports what it finds in the banner and the context, so a slip is caught on the next session instead of sitting in files that load into every one.

Changed

  • A home is identified by its data dir, never by SOUL.md. Every agent's home has a SOUL.md, so that test answered "some agent lives here" when the question is "does this agent live here". Since the home falls back to cwd when the walk finds nothing, the weaker test let one agent read and write inside another's brain.
  • User-level session hooks are no longer supported. Capture ships only with the plugin, which Claude Code loads solely where it's enabled — its own home — so a session can only be captured by the agent whose home it started in. Isolation is structural instead of defended, and the machinery that defended it (self-defer, an enabled-plugin probe, the repeatable --exclude flag) is gone. A session started outside a home is no longer captured at all.
  • The CLI and the MCP tools refuse to run outside this agent's home. Both name the resolved path and the env var that overrides it, rather than reading an empty tree and scaffolding knowledge/ + projects/ into whatever repo you were standing in.
  • README rewritten around the launch-from-home convention, replacing the capture-everywhere recipe, plus a new section on naming and renaming an agent.

Fixed

  • The logger forged the marker that identifies a home. It created the data dir on first write whenever <AGENT>_HOME was set, and it runs on every invocation — including ones the guards had just refused. Point the var at a typo or a sibling agent's home and the refusal itself made the next attempt succeed. Both branches now require the dir to already exist.
  • Field readers walked past an empty value into the next line. \s matches newlines, so **Name:**\s*(.+)$ against a blank field captured whatever followed — an IDENTITY.md with an empty Name made the agent call itself "- Kind: AI assistant" in the banner, in TASKS.md, and in the compile prompts that write its name into long-term memory. Same bug returned type: task as a task's title when title: was blank.
  • Guards no longer recommend a destructive repair. SessionStart told a home with a SOUL.md but no data dir to run init, which offers to overwrite exactly the identity files sitting there; it now names both causes (a restore that lost the dir, or another agent's home) and gives the one-line fix. configure-skills made the same recommendation keyed on a missing CLAUDE.md, which init legitimately writes as CLAUDE.local.md.
  • A blocked task can be cancelled without a detour through active, which had been parking abandoned work in active between the two hops and misreporting it.
  • browser_flows drives chromium over CDP on native Windows (#17).

Upgrade

  • manual: requiredDelete the session-capture hooks and any KEVIN_HOME from ~/.claude/settings.json (and any export KEVIN_HOME in your shell rc). A plugin update can't touch that file. While the hooks remain they still capture, but --exclude is now ignored, so sibling-agent and Ring-1 paths you excluded on purpose are being captured; the CLI warns when it sees the flag. KEVIN_HOME is machine-wide and outranks launch-directory resolution, so it also blocks running a second home. After removing them, always launch from the agent home.
  • manual: nonerestart Claude Code after /plugin update, before anything else. This release rewrites MCP-server code (the home gate, the display-name resolver, the logger, session context) and the running server holds the old code until Claude Code reloads. Deleting the hooks above also only takes effect on relaunch, since the host reads them at launch.
  • template/CLAUDE.md: mandatory — placeholder-only change. Upgrade resolves {{AGENT_NAME}} from your IDENTITY.md before diffing, so for a home whose Name is Kevin the merge is a verified no-op; for a renamed home it arrives in that name.
  • template/SOUL.md: optional — same placeholder-only change, and it's confined to the first line of ## Vibe. If the merge offers you any other section, that is your own earlier customization drifting from the template, not something this release changed — decline it. Accepting would overwrite your edits with the stock text.

templates/IDENTITY.md also changed, and is deliberately not listed above: the edit is confined to the preamble and ## Who, which upgrade never reconciles. That block is your agent's persona, and the avatar line can't survive a diff round trip. New homes only, nothing to do.

[0.3.25] - 2026-08-10

Added

  • list_worktrees — read-only worktree triage. The audit sibling of setup_worktree/remove_worktree: per-worktree branch, dirty and unpushed counts, ahead/behind and merge state vs the base ref (preferring origin/<base>), squash-merge detection via git cherry, last-commit age, and a verdict (deletable / uncommitted / unpushed / pushed-unmerged / missing / main). Also exposed as kevin worktree list <repoPath>; the setup-worktree skill gains the audit rendering + teardown-offer flow, so "which worktrees can I delete?" gets a ranked answer instead of a shrug.
  • github_pr_comments — the GitHub pack can finally read a review. gh pr view's comments field covers the conversation tab only, so a PR whose whole discussion is inline threads read as empty to every tool in the pack. One GraphQL query now returns review threads (path, line, diff side, resolved/outdated state), review submission bodies, and conversation comments.

Fixed

  • Hooks silently degraded when a session roamed out of the HOME tree. The home walk-up started from the shell's cwd, so after a cd into a worktree every subsequent hook found no marker above it and fell back to the pre-init branch: SessionStart handed the agent "run init" in place of its context, and session capture bailed — both silently, because the logger also refuses to write with no home resolved. CLAUDE_PROJECT_DIR (the launch dir, which doesn't roam) now stands in when cwd has wandered off.
  • github_pr_view no longer 403s on repos where CI reports as check runs. It requested statusCheckRollup, a GitHub-App-only capability no fine-grained PAT can hold, which failed the entire view. The field is dropped; github_pr_checks owns that question and fails on its own.
  • GitHub-pack docs matched back to reality. The README tool table had drifted (48 vs an actual 51 — github_fast_forward, curl_run, video_frames never added), the pack-activation blurb and deconfigure list omitted the github_issue_* grants, and the PAT walks told operators to grant Checks — a permission that doesn't exist on fine-grained PATs (Actions: Read answers it). The Contents note now also covers github_pr_diff, and sync's FETCH_FAILED guidance can now discriminate an unapproved token from a missing Contents grant.

Changed

  • Sync's fast-forward docs teach the shared AGENT_* env spellings, with the per-agent prefixed form noted as the override that wins.

Upgrade

  • settings: additive — if you use the GitHub pack, add mcp__plugin_agent-kevin_kevin__github_pr_comments to permissions.allow (new pack homes get it at activation) so review reads don't prompt. Core allow list is unchanged: list_worktrees rides the setup-worktree skill's allowed-tools.
  • manual: none — if your fine-grained PAT was minted from the old walk, check it has Actions: Read (the walk used to name a nonexistent "Checks" permission); without it github_pr_checks can't read check-run CI. Everything else works as-is.

[0.3.24] - 2026-08-07

Added

  • configure-skills Section B — a guided walk for registering external remote MCP servers (an https:// endpoint + bearer token) into <HOME>/.mcp.json via a hardened mcp-remote wrapper. The wrapper fails fast with a loud stderr message when its token is empty, never falls back to $PWD for the secrets path, pins the mcp-remote version, and uses bare-$VAR shell logic (the host interpolates ${VAR} in .mcp.json before the shell runs).

Fixed

  • Browser OAuth tab storm from hand-rolled remote-MCP wrappers. mcp-remote answers a 401 by launching an interactive browser OAuth flow (client registration + authorize tab) and has no flag to disable it. A wrapper that execs it with a silently-empty token — e.g. a secrets path resolved from $PWD in a session launched from a subdirectory — opens a fresh tab on every server spawn, across every session, until the operator kills it. Reported by multiple operators. The Section B wrapper shape makes this unreachable: an empty credential now means one failed server in /mcp, never a browser.

Upgrade

  • manual: required — if your <HOME>/.mcp.json registers any mcp-remote server (grep it for mcp-remote), harden each wrapper to the Section B shape in skills/configure-skills/SKILL.md: add the empty-token fail-fast guard before the exec, replace any $PWD secrets fallback with your absolute HOME path, and pin mcp-remote@0.1.37. Ask Kevin to "harden my remote MCP wrappers per configure-skills Section B" and it will patch and parse-check the file. If the storm is active right now: pkill -f mcp-remote, close the pending authorize tabs without clicking through, then apply the fix and restart sessions. No .mcp.json remote servers → nothing to do. Windows: WSL2 homes use the POSIX wrapper and pkill as-is. Native homes use the pwsh 7+ variant in Section B, and kill an active storm with Get-Process node | Where-Object { $_.CommandLine -match 'mcp-remote' } | Stop-Process -Force (never a blanket node kill).

[0.3.23] - 2026-08-06

Added

  • Sync commits the brain. A new step 11 runs skills/sync/scripts/commit-brain.ts after the dashboard render, so each run's own outputs land in history instead of waiting for someone to remember. The script is the guard, not the model: it acts only when the HOME repo is on main/master with no remote configured, and it never pushes and never amends. Changes are grouped into ordered commits (Sync: update knowledge, Sync: update projects, Sync: save reports, Sync: update state) so the log stays readable. Untracked files outside those roots are reported back as leftUncommitted rather than swept in, and .gitignore still fences secrets. Covered by a 10-case guard matrix including the split-git-dir topology.

Changed

  • Sync's output block gains a 💾 Brain line, and the closing interview moves to step 12.

Upgrade

  • manual: optional — no action for a normal HOME whose .git lives inside the home directory; sync will just start committing. If your HOME uses a split git dir (the git directory outside the home tree), grant that path in .claude/settings.local.json under permissions.additionalDirectories and the sandbox's filesystem.allowWrite, or step 11 will report COMMIT_BLOCKED and change nothing. A HOME repo with a remote configured is skipped by design, since pushing stays your workflow.

[0.3.22] - 2026-08-06

Added

  • Agent-neutral env naming. Every config knob now has a shared, agent-neutral AGENT_* name alongside this agent's own spelling (KEVIN_*), which is derived from the plugin manifest name and always wins. The fork seam collapses to plugin.json plus one test assertion. New side-effect-free shared/naming.ts owns the prefix, the shared/override resolution rule, and the runtime data-dir name (AGENT_RUNTIME_DIR override, validated as a bare folder name). Existing KEVIN_* configs work unchanged — no migration.
  • Init asks which model Kevin runs on (Fable default vs Opus) and writes the literal value to settings.
  • Relocatable reports root. Init's custom-paths step now covers reports/ alongside knowledge/ and projects/ (AGENT_REPORTS), grants the outside-home permissions, and derives plansDirectory from the resolved path.
  • Onboarding plants HOME-scoped env keys under the shared AGENT_* spellings; the README documents the two-spelling rule.

Fixed

  • Prefix derivation fails loud on a missing or malformed plugin manifest instead of silently disabling every per-agent override.
  • The home walk-up and the flow-env secrets gate both honor the default runtime-dir name during a rename migration window, so the secrets store can't be resolved under (or read from) the wrong root.
  • The logger no longer scaffolds a runtime dir in a foreign cwd — a plugin hook firing in someone else's checkout logs to stderr only. Log level/file gain the per-agent override spellings.
  • Bash-driven skills (where-am-i, setup-worktree, init snippets) resolve env vars with the chained two-spelling form instead of reading one spelling literally.
  • The browser-flows harness reads the canonical AGENT_HOME instead of throwing on a missing per-agent variable.

Upgrade

  • manual: none — everything is backward-compatible; existing KEVIN_* settings keep working. Optionally rename HOME-scoped keys (.claude/settings.local.json env, .kevin/secrets/.env KEVIN_DB_*) to the shared AGENT_* spellings for portability — keep KEVIN_HOME prefixed in machine-wide ~/.claude/settings.json on multi-agent machines.

[0.3.21] - 2026-08-05

Fixed

  • init's prerequisite gate could pass on a Mac with no developer tools installed. The checks used command -v, but on macOS /usr/bin/git and /usr/bin/python3 are xcode-select shims — one shared ~118KB binary hard-linked under roughly 78 tool names — that sit on PATH whether or not the Command Line Tools exist. So command -v git succeeded on a machine with no git, init declared prerequisites met, and the failure only surfaced later when something tried to use it. Exactly the fresh-Mac case a non-technical operator arrives with. Verified 2026-08-05: with the developer directory unresolvable, command -v git passes while git --version exits 1. Hard requirements are now functional probes (bun --version, git --version, python3 --version), which also catch a broken install generally.
  • A failing git on macOS now names the right remedy. xcode-select -p is checked, and when the tools are absent init prints xcode-select --install and stops — rather than pointing at a git-scm.com download, which doesn't address the actual cause.

Added

  • Homebrew is surfaced conditionally, not required. Nothing in either plugin calls brew; it's only the install path for gh/poppler on macOS. So it's mentioned only when one of those is missing and the operator would otherwise hit a second wall mid-fix.
  • init probes for gh. The prereq gate checked bun, git, python3 and pdftoppm but not gh — so a missing GitHub CLI passed cleanly and then threw gh CLI not found on PATH mid-session from the first GitHub-pack call, including sync's code refresh. Now surfaced as a conditional NOTE ("needed only if you activate the GitHub pack"), since nothing outside that pack uses it. The prose also records where the macOS toolchain actually comes from: git and python3 ship with the Xcode Command Line Tools and need no Homebrew, whereas gh is bundled with neither Claude Code nor this plugin and therefore does.
  • The GitHub pack walk checks gh before granting. configure-skills stated the requirement in prose but never verified it, so the pack could activate cleanly and fail on first use. It now probes and offers a choice — continue and install after, or stop and come back — rather than hard-stopping, because the PAT-minting steps are still worth doing in the same sitting.

Changed

  • The GitHub pack is default-ticked when a code path was given at Step 4b. github_fast_forward needs GITHUB_TOKEN; without the pack it returns NOT_CONFIGURED and the operator's checkouts silently never refresh. That's the one failure mode that degrades answers rather than raising an error — Kevin keeps grounding confidently against a frozen checkout — and an operator who just told init where their code lives has effectively asked for the opposite. Still unticked when Step 4b returned skip, which stays the common case for a Kevin home.

Upgrade

  • manual: none — if you activated the GitHub pack before this release, confirm gh is on your PATH (command -v gh; macOS brew install gh). Nothing else to reconcile.

[0.3.20] - 2026-08-05

Added

  • github_fast_forward — sync step 0 moves into the GitHub tool family. Fast-forwards the default branches of the configured checkouts by slot (first local match of main/master, and of develop/dev), so a vestigial master beside a live main is never touched. Authenticates with the existing fine-grained read-only PAT over HTTPS: one fetch --prune per repo, then every ref update is local and needs no credential. The checkout's own remote is neither used for transport nor rewritten, so an SSH remote keeps working for the operator's own pushes. Guard matrix pinned by tests in mcp-server/src/tools/github.test.ts.

Fixed

  • Sync step 0 was a guaranteed no-op in any sandboxed session. It ran git fetch through the Bash tool, and the Claude Code seatbelt gives non-proxied clients no DNS at all — so every repo with a git@github.com: remote failed at hostname resolution. It also reported that as FETCH_FAILED, conflating "no egress from this process" with "this repo is broken." Moving the work into the MCP server (which runs outside the sandbox, the same reason the rest of github_* lives there) fixes it, and FETCH_FAILED now carries a reason of NO_ACCESS / AUTH / NETWORK so the report says which.
  • A PAT the org hasn't approved is no longer misreported as a bad credential. Verified against a live org: GitHub answers 403 on the git endpoint in that case, which the classifier scored as AUTH — telling the operator to re-mint a token that was perfectly valid. AUTH is now only for a credential GitHub rejects outright; 403, 404 Repository not found, and permission denied all read as NO_ACCESS, whose fix is the Contents grant plus org approval.
  • The GitHub PAT scope list was missing Contents: Read and actively told operators they didn't need it. git fetch authenticates against Contents, so a token minted from the old instructions fails the fast-forward as NO_ACCESS while the PR and issue tools work fine. Contents: Read confers no push ability; writing needs Contents: Write, which is never requested.
  • config froze every filesystem path at import time, so whichever module imported it first decided where the whole process wrote. Anything that set KEVIN_HOME afterwards — a hook, the CLI, a test fixture — was silently ignored. FOLDERS and FILES are now getters that resolve live per access, so the existing call sites are unchanged and import order no longer decides anything. The concrete hazard: because Bun runs every test file in one process, a single unrelated import in an early-loading test file could freeze config to the operator's real home and have the session-capture suite write fixture data into their actual knowledge/raw/sessions/. A new bunfig.toml preload now pins KEVIN_HOME to a throwaway tree for every suite, so that's structurally impossible regardless of import order, and config.test.ts pins the live-resolution behaviour.
  • Secret loading had the same import-time freeze. loadSecretsEnv() latched on a boolean and ran eagerly at import, so the first module to pull shared/env decided which home's .kevin/secrets/.env the process used forever — the per-read calls could never correct it, making the module's own "no import-order discipline to forget" promise untrue. It's now keyed on the resolved secrets file, so a changed KEVIN_HOME re-reads (and drops the previous store's keys so they can't leak across homes).
  • Six modules still froze a home-relative path at import, re-introducing the import-order hazard the getters removed. session-capture's lock dir, status/collect's TASKS.md path, browser-flows' HOME flows dir, google-auth's secrets subpaths, and the captures dir in tools/browser + media/frames were all module-scope consts built from FOLDERS getters — frozen to whatever home was current at first import. Each now resolves at call time (the two captures dirs reuse config's existing BROWSER.CAPTURES_DIR getter instead of re-deriving the path); google-auth's unconsumed CLIENT_FILE export dropped along the way.

Changed

  • init no longer grants the fast-forward git verbs (git fetch, git merge --ff-only, git rev-parse, git show-ref). They existed only for the Bash version of step 0; the MCP tool needs none of them, so the baseline goes back to being tighter.
  • Step 0 is now GitHub-pack-gated, and never fails the chain. A home without GITHUB_TOKEN gets a NOT_CONFIGURED report rather than a tool error, and a home with no codebase at all — common for Kevin — reports an empty list instead of erroring, so the rest of the sync chain runs untouched either way.
  • config owns the configured-checkout list. configuredRepoPaths() (KEVIN_CODE_PATH plus KEVIN_GIT_REPOS, deduped after tilde expansion) and extraGitRepos() both live there and resolve live, replacing a frozen EXTRA_GIT_REPOS const and a duplicate parse inside the GitHub tool. Tilde expansion now happens once, at the input boundary.
  • expandTilde has one owner. Three copies had accumulated in config.ts, shared/env.ts, and shared/utils.ts — every shared home for it blocked by an import cycle — and they had already drifted, with two handling ~/foo but not a bare ~. It now lives in shared/paths.ts, a stdlib-only leaf every layer can import. A follow-up sweep found two more private variants (tools/github.ts, plus an inline one in media/frames.ts that mangled a bare ~); both now import the shared helper, and the bunfig.toml comment now says "agent home" rather than a specific env var, so the file stays fork-agnostic.
  • Five workaround rationales corrected, one simplification taken. curl.ts no longer imports @/config lazily inside its handler to dodge the freeze; status/html.ts, status/html.test.ts, tasks/prefix.test.ts, tools/upgrade.test.ts, and shared/env.ts's header all described a constraint that no longer exists. bin/kevin keeps its dynamic imports — the specifiers are computed from the plugin root, so they cannot be static, and they load one subsystem per invocation instead of all of them — but its comment now names those reasons instead of the env-ordering one.

Upgrade

  • settings: additive — add mcp__plugin_agent-kevin_kevin__github_fast_forward to permissions.allow if you use the GitHub pack, so /agent-kevin:sync step 0 doesn't confirm per run.
  • template/CLAUDE.md: mandatory — new "Scratch files get a mktemp name" rule under Platform ($TMPDIR is per-user, concurrent sessions clobber fixed names).
  • manual: none — if you minted your PAT before this release, add Contents: Read to it (Repository permissions, read-only). Without it step 0 reports NO_ACCESS. Everything else in the GitHub pack keeps working either way.

[0.3.19] - 2026-08-03

Added

  • sync step 0 — fast-forward the code checkouts. Before the knowledge chain runs, sync fetches every repo in KEVIN_CODE_PATH + KEVIN_GIT_REPOS and fast-forwards whichever of main / master / develop / dev already exist locally. Makes /agent-kevin:sync the single command a non-technical operator ever has to run — code freshness rides along instead of being a git chore they'd have to remember. Engineers benefit too: default branches in reference checkouts stop drifting weeks behind. Both env vars are optional, so a Kevin with no codebase configured skips the step silently. Strictly forward-only and heavily guarded — only branches that already exist locally are touched (never conjures a develop), non-fast-forward updates are refused rather than forced, a dirty checked-out branch is reported as SKIPPED_DIRTY and left alone, main checkouts only (a worktree's .git is a file), and a failed fetch degrades to a report line instead of failing the sync. Outcomes surface in a new 🖥 Code block.

    Safe for heavy multi-worktree work, verified empirically against git 2.50 rather than assumed. The step runs only fetch, merge --ff-only, and read-only queries — it never checks out, stashes, resets, rebases, cleans or commits, so a current branch cannot be switched underneath the operator. A branch checked out in a linked worktree is refused by git (refusing to fetch into branch … checked out at …) and reported as the informational CLAIMED_BY_WORKTREE rather than being conflated with a real divergence; a live worktree holding uncommitted work came through a full run with its HEAD, tracked changes and untracked files untouched. An in-progress rebase is likewise refused and survives intact, detached HEAD only ever sees a ref move (no file, index or HEAD change), and --prune removes remote-tracking refs without deleting local branches.

Changed

  • init grants the fast-forward git verbs (git fetch, git merge --ff-only, git rev-parse, git show-ref) in the baseline permissions.allow, so sync's step 0 doesn't prompt mid-run. Nothing destructive is added — force/reset/rebase stay denied.

Fixed

  • upgrade no longer reconciles a home against a stale template set when the loaded plugin is a version-pinned cache dir. The version still comes from CLAUDE_PLUGIN_ROOT (never installed_plugins.json, whose record lags a directory-type marketplace), but when that root is a plugins/cache/<mkt>/<plugin>/<version> copy, the skill now reads the marketplace source's plugin.json and reports available=. A newer source version stops the run with the /plugin marketplace update/plugin update → restart path, because the CHANGELOG bundled beside a pinned copy cannot describe migrations released after it. Advisory and best-effort: any lookup miss leaves available empty and changes nothing.

Upgrade

  • settings: additive — add Bash(git fetch *), Bash(git merge --ff-only *), Bash(git rev-parse *), Bash(git show-ref *) to permissions.allow so /agent-kevin:sync can refresh your checkouts without a prompt per repo. Union merge, nothing removed.

[0.3.18] - 2026-08-03

Added

  • where-am-i checkpoint mode (/agent-kevin:where-am-i checkpoint): writes a short pickup note for the current session as a chat reply, so the SessionEnd capture files it into knowledge. Incremental by construction, no cursor or state file.
  • Dashboard Surfaces group in the sidebar, discovered from disk on every render: a HOME-root roadmap.html leads, then every projects/<slug>/dashboard.html, alphabetically. Zero config, no registry.
  • Malformed-task health signal: task files whose frontmatter won't parse are collected and surfaced as a warning callout in TASKS.md plus a fifth blocking dashboard signal, instead of silently vanishing from every scan.
  • init recommends the split layout (~/Documents/Agents/<AgentName> for the home, repos in a separate code tree), refuses to scaffold into a code repo without confirmation, and flags iCloud Documents sync.

Changed

  • Agent home resolution goes through a shared .kevin-marker walk-up (agentHomePath() / isAgentHome()): KEVIN_HOME wins, else walk up from cwd anchoring on this agent's data dir, else cwd (pre-init only). A session launched inside a code repo can no longer anchor .kevin/ state, captures, or logs to that repo.
  • Mutating skills (upgrade, sync, configure-skills, the goals watermarks, cadence) fail loud with NOT_AN_AGENT_HOME rather than writing into whatever tree the session ran in. The goals skills' inline watermark one-liners collapse into a shared watermark.ts.
  • init writes permissions.additionalDirectories and sandbox.filesystem.allowWrite for the code root whenever KEVIN_CODE_PATH resolves outside the home, and derives KEVIN_GIT_REPOS from the main-checkout repos beside it (.git directories only, so sibling worktrees don't flood the list).
  • where-am-i takes comma-separated scope roots (cwd + home + code root) so the radar sees home and code-repo sessions across separate trees; setup-worktree guidance points at the code root.
  • api-collections Bruno adapter notes the Bruno v4 deltas (setEnvVar now persists → secrets rule); roadmap render check notes the entry-animation blank-section pitfall.

Fixed

  • Session radar prefers an operator's /rename custom title over the first-prompt auto-title (matching Claude Code's own customTitle || aiTitle precedence), so restored sessions stop being named after the "catch up and continue" instruction.

Upgrade

  • template/CLAUDE.md: mandatory — Knowledge Structure and Git Worktrees sections describe the split layout (~/Documents/Agents/<AgentName> home, repos in a separate code tree).
  • settings: optional — when your code tree lives outside the home, add permissions.additionalDirectories: ["<CODE_ROOT>"] and sandbox.filesystem.allowWrite: ["<CODE_ROOT>"] (code root, not a single repo, so sibling worktrees and a separated agent git dir stay writable). Skip for nested homes or homes with no code path.
  • manual: nonerestart Claude Code after /plugin update, before syncing. This release changes MCP-server code (home resolution, dashboard, task scan); the running server holds the old code until Claude Code reloads, so a sync before the restart runs against a stale server.
  • manual: none — optionally widen KEVIN_GIT_REPOS in .claude/settings.local.json to the repos beside KEVIN_CODE_PATH (comma-separated) for a fuller SessionStart git-activity block.

[0.3.17] - 2026-07-30

Added

  • roadmap skill: wizard-built strategic roadmap surfaces — interviews for the frame (shape, horizons, lanes, accent scheme), harvests milestones from the task board / READMEs / git history, renders a self-contained dark/light HTML page from the house template (references/template.html + DESIGN.md). Model-invocable; fires on "roadmap", "north star", "plan-on-a-page" asks.
  • Accent-scheme presets in the roadmap wizard: purple (template default), green, gold, or a typed hue via Other; DESIGN.md carries the token sets and per-preset dark tints.

Changed

  • init allow list gains Skill(agent-kevin:roadmap) so auto-invocation never prompts.

Upgrade

  • settings: mandatory — add permission Skill(agent-kevin:roadmap).

[0.3.16] - 2026-07-24

Added

  • Dashboard operator card is travel-aware: when KEVIN_HOME_TIMEZONE differs from the machine's live timezone, the card (sidebar + Profile header) stacks 🏠 <home> over ✈️ <current>. At home it stays a single plain timezone line, unchanged.

Changed

  • morning-briefing and sync skills name the Perplexity web_search tool explicitly instead of built-in WebSearch, so the briefing's news pull uses the intended provider.

Fixed

  • Dashboard operator card renders only the IANA token of the home timezone, stripping any annotation carried on the timezone field.

Upgrade

  • None — code-only, no bun install or HOME changes.

[0.3.15] - 2026-07-24

Added

  • Travel-aware timezone: set KEVIN_HOME_TIMEZONE (IANA name) in .claude/settings.local.json envinit now writes it from Step 4. When it differs from the machine's live timezone, the SessionStart ## Today line appends ✈️ traveling (home: <tz>). Unset leaves output unchanged.

Changed

  • templates/USER.md + init: the single Timezone identity field splits into Home timezone (static home base) and Current timezone (read from the session context's ## Today line, follows travel).
  • Morning/evening briefings compute the Hijri date in the operator's current timezone (the ## Today line), falling back to the home timezone in USER.md.
  • Dashboard operator card reads the new Home timezone field, with fallback to the legacy Timezone label.

Upgrade

  • template/USER.md: optional — Timezone line splits into Home/Current timezone.
  • script: required — runs skills/upgrade/scripts/0.3.15.ts: seeds KEVIN_HOME_TIMEZONE in .claude/settings.local.json env from USER.md's home timezone (no-op if already set; reports when USER.md has no valid IANA name so the operator can set it by hand).

[0.3.14] - 2026-07-23

Added

  • where-am-i triage mode (/agent-kevin:where-am-i triage [scope], or when the operator asks "what should I tend to / work on next / which session needs me"): ranks the live sessions by what most needs a human (decision-pending, importance, momentum), presents the top few via an AskUserQuestion interview, and hands back the claude --resume command for the chosen one. Ephemeral — no report.
  • where-am-i standard digest now leads with a compact index table (one row per session, state emoji first) above the buckets; skipped when there are ≤2 sessions.
  • init prerequisite check now notes poppler as an optional dependency — the Read tool renders PDF pages via its pdftoppm binary (brew install poppler / poppler-utils).

Changed

  • init engineering defaults: when a built-in tool reports a missing dependency, relay its install hint and stop rather than improvising a fragile fallback.

Upgrade

  • None — code-only, no bun install or HOME changes.

[0.3.13] - 2026-07-16

Added

  • api-collections skill: draft API request collections the operator opens and fires from their own client. Client-agnostic core with per-client adapters (Bruno shipped; plain-curl fallback when no client is installed). The Bruno adapter warns about its silent soft-failures (malformed-YAML drop, .env-read-at-open, unresolved-placeholder false green) and parse-checks each file after authoring.
  • curl_run MCP tool: run an authored request end-to-end to verify it before handing it off (the api-collections verification path).
  • browser_screenshot and browser_pdf accept a CSS-injection input to tweak the page before capture (#16).
  • Flow-scoped secrets (.env) and QA fixtures (config.json) for HOME browser flows.

Upgrade

  • settings: mandatory — add two allow-list entries to the HOME's .claude/settings.json: mcp__plugin_agent-kevin_kevin__curl_run (new always-on core tool) and Skill(agent-kevin:api-collections) (new model-invocable skill).

[0.3.12] - 2026-07-13

Added

  • browser_flows now discovers flow definitions from the HOME's .claude/browser-flows/ directory, so an operator can author reusable browser flows in their own home alongside the plugin-shipped ones.

Fixed

  • Robust worktree teardown on native Windows: kills processes holding the worktree, requires PowerShell 7+ (pwsh), and fully tears down the checkout instead of leaving a husk.

Upgrade

  • template/CLAUDE.md: mandatory — new note under the Platform section: on native Windows, PowerShell 7+ (pwsh) is required (scripts never use the built-in 5.1 powershell.exe).

[0.3.11] - 2026-07-12

Added

  • video_frames MCP tool — extracts still frames from a local video for visual analysis, running outside the Bash sandbox so it can read videos in ~/Downloads, ~/Desktop, ~/Documents (which ffmpeg-under-Bash can't). Modes: scene (default — one frame per visual change, ideal for screen recordings of a flow), interval, count. Requires ffmpeg on PATH.
  • mermaid skill — validates and iterates on a Mermaid diagram before it ships (Tier 1 parse-check every block; Tier 2 render + visual critique for diagrams headed to a rendered surface). Runs on /mermaid.
  • permission-check skill — interprets a Claude Code permission prompt from a screenshot (or text) and grades how safe it is to allow (🟢/🟡/🔴), then writes a graded report so repeated decisions build a corpus for future allowlist automation.
  • permissions report category — home for permission-check output; surfaces as a dashboard filter chip.

Changed

  • Database tools (database_query, database_schema, database_fork) now accept any legal Postgres database name, not just a fixed pattern.
  • README refresh.

Upgrade

  • deps: required — new dep mermaid (~11.16.0); run bun install in mcp-server.
  • settings: mandatory — add to permissions.allow: mcp__plugin_agent-kevin_kevin__video_frames, Skill(agent-kevin:mermaid), Skill(agent-kevin:permission-check).
  • manual: nonevideo_frames needs ffmpeg on PATH to run (brew install ffmpeg); only required if you use the tool.

[0.3.10] - 2026-07-09

Added

  • CLAUDE.md template now carries a truncated-read verification rule in ## Workflow: a partial file read is never a basis for a conclusion — when a Read returns a partial view (or you've only seen part of a query, match-set, or config), page through or grep the rest before asserting, labeling, or acting on it.

Upgrade

  • template/CLAUDE.md: mandatory — add the truncated-read verification bullet to your HOME CLAUDE.md## Workflow (right after the "Verify before claim" line).

[0.3.9] - 2026-07-09

Added

  • CLAUDE.md template now carries a forward-only git rule in ## Workflow: fix a bad commit with a new commit on top (git revert or a corrective commit), never --amend, rebase -i squash/fixup, or reset + rebuild — even when local and unpushed.

Changed

  • sync skill's step-11 closing interview + "Suggested next moves" now freshness-check every candidate against current ground truth (task frontmatter, live artifacts, today's deltas) before offering it, so it stops surfacing next-moves the operator already completed.

Upgrade

  • template/CLAUDE.md: mandatory — add the forward-only git bullet to your HOME CLAUDE.md## Workflow.

[0.3.8] - 2026-07-09

Added

  • remove_worktree MCP tool — safe git-worktree teardown that runs outside the Bash sandbox (so git worktree remove can write the main repo's .git/config). Refuses on uncommitted changes (blocked-uncommitted), gates committed-but-unpushed work behind an explicit force (blocked-unpushed), supports a dryRun pre-check, never --force-removes, runs the repo's clean script when present, and leaves the branch intact unless deleteBranch is set. Deliberately not granted in settings.json: it's destructive, so each call prompts for confirmation.
  • setup-worktree skill gained a drop/teardown flow (dry-run pre-check → unwire the VS Code workspace → remove) and, when the GitHub pack is configured, surfaces the branch's PR state to reframe a merged-branch "unpushed" result and frame the branch-delete ask.
  • Native-Windows headless-browser support: Chromium is driven over CDP with a ws transport, working around a Bun pipe-transport hang; ships a pinned playwright (1.60.0) with a playwright-core patch.

Upgrade

  • deps: required — new dependency ws; playwright pinned to 1.60.0 with a playwright-core@1.60.0 patch. Run bun install in mcp-server.

[0.3.7] - 2026-07-06

Fixed

  • Report-writing skills (where-am-i, flywheel, morning-briefing, evening-briefing, self-review, weekly-goals, monthly-goals, yearly-goals) now surface the absolute path returned by report_write instead of the relative relPath, so the "📄 Saved to …" line is command-clickable in any terminal (e.g. cmux) without a base directory.

Upgrade

  • None — code-only, no bun install or HOME changes.

[0.3.6] - 2026-07-01

Changed

  • .env deny baseline in /init narrowed: the catch-all Read(**/.env.*) is replaced by explicit denies for the secret-bearing variants (.env.local, .env.*.local, .env.development, .env.production, .env.staging, .env.test). Template files (.env.example, .env.sample, .env.template) now read freely, since Claude Code evaluates deny before allow with no glob negation, so narrowing the deny is the only way to whitelist one file. The bare .env stays denied; secrets in .kevin/secrets/ are unaffected.

Upgrade

  • settings: optional — in .claude/settings.jsonpermissions.deny, replace Read(**/.env.*) with Read(**/.env.local), Read(**/.env.*.local), Read(**/.env.development), Read(**/.env.production), Read(**/.env.staging), Read(**/.env.test). Purely a relaxation so .env.example becomes readable; skip if you prefer the broader deny.

[0.3.5] - 2026-06-30

Added

  • sync now closes with a next-steps interview: after the dashboard render, it turns the surfaced backlog into a single AskUserQuestion. Pick a concrete next move (a suggested move, a flagged overdue/stale item, a due cadence skill, or a pending upgrade), then act on it now or queue it as a task. Gated to fire only when something is actually surfaced; a clean bill still ends on the ✅ Sync complete one-liner. Cadence/upgrade picks collapse to surfacing the slash command (they stay operator-gated).

Upgrade

  • None — code-only, no bun install or HOME changes.

[0.3.4] - 2026-06-25

Added

  • Read-only GitHub pack: nine MCP tools that shell out to gh --jsongithub_pr_list / github_pr_view / github_pr_diff / github_pr_checks, github_run_list / github_run_view / github_run_log, and github_issue_list / github_issue_view. Lets Kevin review PRs and issues, pull diffs and check status, and diagnose failing GitHub Actions runs (failed-step logs). No write subcommands — commenting, merging, and re-running workflows stay human-in-terminal by design. Runs from inside the MCP server (outside the Bash sandbox, where gh's keychain TLS would otherwise fail), authenticating via a GITHUB_TOKEN from .kevin/secrets/.env. Repo defaults to origin of KEVIN_CODE_PATH / first KEVIN_GIT_REPOS entry; override per-call with repo="owner/repo".
  • GitHub is now an opt-in pack in /init and configure-skills (new A.2d walk), alongside SEO / Browser / Database.

Changed

  • self-review and yearly-goals skills now persist their summaries via the report_write MCP tool, so each run leaves a durable report in the audit trail.

Upgrade

  • settings: optional — the GitHub pack is opt-in. To activate, run /agent-kevin:configure-skills (GitHub walk): it grants the nine github_* tool permissions, ensures .kevin/secrets/.env, and surfaces the steps to mint a fine-grained read-only PAT (GITHUB_TOKEN). Requires the gh CLI on PATH (brew install gh). Existing homes are unaffected until they opt in.

[0.3.3] - 2026-06-25

Added

  • Sync now surfaces cadence nudges: planning and review skills (the weekly/monthly/yearly-goals trio + self-review) that have come due are listed with the exact slash command to run, driven by a cadence block in each skill and a shared skills/sync/scripts/cadence.ts.
  • Dashboard Skills tab gained auto/manual filter chips so you can split model-invocable skills from slash-only ones.
  • kevin CLI gained a database command group (list/schema/query/fork) mirroring the Database MCP tools for use outside Claude Code.

Changed

  • Consolidated every process.env read into a single config-free shared/env.ts module. Secret-reading tools (web-search, serpapi, open-page-rank, gsc, database, database_fork) now self-load .kevin/secrets/.env on first access regardless of import order, instead of relying on a sibling importing config.ts first. A build-time guard test fails if any module outside shared/env.ts reads process.env directly.
  • self-review skill: fixed path drift, added an output watermark and a template-promotion track.
  • Dashboard settings/env/secrets tables now wrap long values instead of overflowing.

Fixed

  • Sandbox secrets deny never bit. v0.3.0/v0.3.1 wrote the secrets deny under sandbox.filesystem.read.denyOnly — the harness's internal resolved shape, not a real settings input key — so Claude Code silently ignored it and files nested under .kevin/secrets/ (Google OAuth tokens, .kevin/secrets/.env) stayed readable by sandboxed Bash, even though ls of the dir was blocked. The real key is sandbox.filesystem.denyRead; pointing it at the directory (no glob) denies it and everything under it at the OS level, which also sidesteps the gitignore **-won't-descend-into-.kevin dot-dir trap. /init now scaffolds denyRead plus a forward-compatible sandbox.credentials.files entry (honored on Claude Code v2.1.187+, ignored on older).

Upgrade

  • script: required — run skills/upgrade/scripts/0.3.3.ts via the run_upgrade MCP tool. It drops the dead sandbox.filesystem.read.denyOnly key, adds sandbox.filesystem.denyRead: [".kevin/secrets"], and seeds sandbox.credentials.files. Idempotent.
  • manual: none — restart/reload Claude Code after the migration so Seatbelt loads the corrected policy. Verify with wc -c < .kevin/secrets/<a-token-file> — it should report "Operation not permitted" (not a byte count).

[0.3.2] - 2026-06-24

Added

  • New database_fork MCP tool: clones a Postgres database into a private copy via CREATE DATABASE <fork> TEMPLATE <source> (pure SQL, no pg_dump/pg_restore, cross-platform), so risky or destructive schema work runs against a scratch copy instead of a shared/live DB. Refuses remote hosts (local only), defaults to the first connection, names the fork after the current git branch, can repoint an env file at the fork, and tears down with drop: true. This is what setup-worktree now uses to give a worktree its own database on demand.
  • Dashboard now shows a presence-only secrets inventory of .kevin/secrets/ (env key names + Google OAuth files): names and presence checks only, never values.

Changed

  • Database tools renamed for consistency: db_listdatabase_list, db_schemadatabase_schema, db_querydatabase_query. Consumer-visible (permission grants change; see Upgrade).
  • setup-worktree skill wires up database_fork to provision a worktree's database.
  • README database section rewritten for the v0.3.0 secrets layout: KEVIN_DB_* connection strings now live in .kevin/secrets/.env, not settings.local.json.

Fixed

  • Hardened the not-yet-released 0.3.0.ts / 0.3.1.ts secrets migrations: purge the old settings.local.json env block after relocation and strengthen the secrets deny path.

Upgrade

  • settings: mandatory — only if you use the Database pack. Replace the renamed tool grants in your project .claude/settings.json: remove mcp__plugin_agent-kevin_kevin__db_list, mcp__plugin_agent-kevin_kevin__db_query, mcp__plugin_agent-kevin_kevin__db_schema; add mcp__plugin_agent-kevin_kevin__database_list, mcp__plugin_agent-kevin_kevin__database_query, mcp__plugin_agent-kevin_kevin__database_schema, mcp__plugin_agent-kevin_kevin__database_fork.

[0.3.1] - 2026-06-24

Fixed

  • Completed the secret-file deny baseline for homes upgraded via the contract. v0.3.0 broadened /init's permissions.deny (the dotenv / cert / credential globs plus the two curl … | sh Bash denies) and its narrow sandbox denyOnly, but the v0.3.0 migration wrote only the secrets-dir Read deny — so a home that ran /upgrade (rather than a fresh /init) was left with just Read(**/.kevin/secrets/**) and missed the rest of the hardening.

Changed

  • google-auth tool gained a comment documenting the secrets-dir layout (parity with the worktree + Walle).

Upgrade

  • script: required — run skills/upgrade/scripts/0.3.1.ts via run_upgrade. Tops the project .claude/settings.json up to the full /init baseline: adds the remaining Read denies (**/.env, **/.env.*, **/secrets/**, **/credentials/**, **/*.pem, **/*.key) and the two curl … | sh Bash denies to permissions.deny, and **/.env + **/.env.* to the sandbox filesystem.read.denyOnly. Additive and idempotent — never removes or reorders existing entries. Touches only the project settings file, never the global ~/.claude/settings.json.

[0.3.0] - 2026-06-24

Added

  • Secrets are centralized into a deny-gated .kevin/secrets/ directory: credential env vars (PERPLEXITY_API_KEY, SERPAPI_KEY, OPENPAGERANK_API_KEY, KEVIN_DB_*) live in .kevin/secrets/.env and Google OAuth files in .kevin/secrets/google/, loaded once at boot by the MCP server / CLI and never exposed to ad-hoc Bash. A Read(**/.kevin/secrets/**) deny keeps the agent from reading its own secrets.
  • Versioned upgrade-script mechanism: a heavy one-time HOME migration ships at skills/upgrade/scripts/<version>.ts and runs via the new always-on run_upgrade MCP tool (outside the Bash sandbox, so it can touch deny-gated paths). Scripts are self-contained, idempotent, fail-loud, and pruned once the minimum baseline passes them.

Changed

  • /agent-kevin:upgrade now runs script:-tagged migrations through run_upgrade; /agent-kevin:release detects an in-range migration script and locks the version to its filename instead of asking for a bump.
  • init and configure-skills skills updated for the secrets layout and the new always-on core tool list.

Upgrade

  • script: required — run skills/upgrade/scripts/0.3.0.ts via run_upgrade (relocates secrets to .kevin/secrets/ and writes the Read deny). Breaking HOME-layout move; idempotent and verified before it strips the originals.
  • settings: mandatory — add permission mcp__plugin_agent-kevin_kevin__run_upgrade (new always-on core tool) and the deny Read(**/.kevin/secrets/**).

[0.2.9] - 2026-06-23

Added

  • Dashboard Tasks page now has project filter chips (All + one per project, busiest first, with the project's color dot), mirroring the Reports page. They appear on both the agenda and the Needs-attention view, and stay hidden when there's only one project to filter between.
  • Task rows show a 💬 comment counter chip (thread entry count) in the summary, and depends on ids in the expanded body now link to their task files (live or archived).

Changed

  • Redesigned the expanded task-detail body: a quiet, dot-separated key/value meta block (status · due · updated · depends on) replaces the old ·-joined dim line, with the blocker reason on its own amber-edged note line. The id itself is now the open-the-file link (no separate footer).
  • Needs-attention view rebuilt: Blocked and Going-stale are filterable grouped rows under one filter box (Blocked reads as a single id · why · project row) instead of two separate tables.
  • Plugin description updated to engine-agnostic tool wording (headless browser / web search, not Playwright / Perplexity) and a stable "20+ skills" count.

Upgrade

  • None — code-only, no bun install or HOME changes.

[0.2.8] - 2026-06-23

Fixed

  • Task prefix resolution is now consistent end-to-end. buildPrefixMap gives a project whose prefix is inferred from existing task files precedence over an empty project that derives the same prefix, so an empty project can no longer displace a tasked project's IDs (which would misroute findTaskById). getNextId now mints IDs through the same collision-resolved prefix that findTaskById looks up, removing a second source of truth.
  • create-project and archive-project skills: removed references to the deleted hardcoded TASKS.PREFIX_MAP (prefixes are now filesystem-derived), corrected stale app/ paths to mcp-server/, fixed malformed MCP tool invocations, and dropped the dead HEARTBEAT.md cleanup step.

Changed

  • Pure task-prefix logic extracted to mcp-server/src/tasks/prefix.ts (derivePrefix, assignPrefixes), keeping scan.ts as the filesystem wiring and making the logic unit-testable without a config-backed HOME.

Upgrade

  • None — code-only, no bun install or HOME changes.

[0.2.7] - 2026-06-22

Fixed

  • SessionStart banner: the "upgrade available" row now matches the Label: value shape of the Agent/Knowledge/Projects rows (⬆️ Upgrade: run ...) and drops the em-dash, so it aligns with the sibling lines.

Upgrade

  • None — code-only, no bun install or HOME changes.

[0.2.6] - 2026-06-21

Changed

  • templates/CLAUDE.md engineering standards gain a Comments subsection: default to no comment, keep only the why, JSDoc-for-consumer-APIs only (always multi-line), no tombstones/archaeology, and fix the name or abstraction instead of explaining awkward code.

Upgrade

  • template/CLAUDE.md: mandatory — new "Comments" subsection under Engineering Standards. Additive content; appended after "Code style".

[0.2.5] - 2026-06-21

Changed

  • sync now checks for a pending plugin upgrade as part of its needs-attention step: it compares the installed plugin version against the home's migrated baseline (.kevin/version.json) and surfaces a dedicated ⬆️ Upgrade line in the report when they drift. The check is read-only: sync never runs /upgrade; the migration stays an operator-gated command. Mirrors the dashboard staleness-warning pattern.

Fixed

  • Dashboard persona-head no longer repeats the agent name + emoji next to the avatar (it already appears in the page title).

Upgrade

  • None — code-only, no bun install or HOME changes.

[0.2.4] - 2026-06-20

Changed

  • The sync skill is now model-invocable (dropped disable-model-invocation), so Kevin can run a full state refresh on its own and other skills can chain it via the Skill tool (/upgrade now chains sync after applying a HOME migration). Added to the canonical onboarding grant list (eight → nine skill grants).

Upgrade

  • settings: mandatory — add permission Skill(agent-kevin:sync) to settings.jsonpermissions.allow. Without it, model invocations of sync (including the chain from /upgrade) prompt for confirmation each time.

[0.2.3] - 2026-06-20

Added

  • Dashboard now surfaces each session's tasks and plans (radar-refs), so the activity view links straight to the work a session touched.
  • Database tool: target a specific database per query and support db-less connections (db_query accepts a per-call database; connections without a default database now work). (#5)

Changed

  • Engine-agnostic MCP tool names. The browser tools playwright_screenshot/playwright_pdf/playwright_markdown/playwright_record are renamed to browser_screenshot/browser_pdf/browser_markdown/browser_record, and perplexity_search is renamed to web_search. The underlying engines are unchanged; only the tool names are now engine-neutral. (browser_flows keeps its name.)
  • Dashboard History: doubled the captured-briefing snippet cap to 240 chars.
  • release skill: now asks the maintainer which bump to take (patch/minor/major, each shown with its concrete target version) and, after staging, asks how far to go (commit / commit + tag / commit + tag + push) instead of free-text proposing.
  • README: promoted the upgrade/release docs to their own section and simplified the diagram.

Fixed

  • Upgrade-available alert spacing in the dashboard.

Upgrade

  • settings: mandatory — only if the Browser pack is active. The renamed tools need their permissions.allow grants in settings.json swapped: remove the old names and add the new ones — mcp__plugin_agent-kevin_kevin__perplexity_search…web_search, …playwright_screenshot…browser_screenshot, …playwright_pdf…browser_pdf, …playwright_markdown…browser_markdown, …playwright_record…browser_record. (…browser_flows is unchanged.) Homes that never activated the Browser pack have no playwright/perplexity grants and need no change.

[0.2.2] - 2026-06-20

Fixed

  • init and upgrade skills: the gitignore-tracking logic used the shell ! negation operator, which fails in the Claude Code Bash tool's eval wrapper (command not found: !). Rewritten to be fully !-free (nested if/else, octal \041 for the literal !), so the .kevin/version.json and compile-cursor negations land regardless of shell. Completes the shell-! hardening begun in 0.2.1.

Changed

  • README: added a "How upgrades & releases work" section documenting the two-phase model (plugin code vs. home reconciliation), local behind-detection, the consumer/maintainer flows, and the Upgrade-block format.

Upgrade

None — code-only, no bun install or HOME changes.

[0.2.1] - 2026-06-20

Fixed

  • init and upgrade skills: a literal leading ! in a shell command can be mangled to \! by some interactive shells (zsh history expansion), which silently broke the .gitignore negations that keep .kevin/version.json and the compile cursor git-tracked. The ! is now emitted via its octal code \041 and existence is detected with !-free greps, so the negations land regardless of shell.

Upgrade

None — code-only, no bun install or HOME changes.

[0.2.0] - 2026-06-20

Versioned release + upgrade tracking. /plugin update refreshes plugin code but never touches a home's scaffolded files or runs bun install; this release adds the contract and tooling to close that gap.

Added

  • /agent-kevin:upgrade — applies pending HOME migrations after a /plugin update: runs bun install when a release needs it, auto-applies functionality-critical changes (permissions, new rule/concept files), and asks before touching anything you may have personalized (a SOUL/CLAUDE section). Handles being several versions behind in one pass, backs up to .kevin/updates/ first, and ends with a sync.
  • /agent-kevin:release — producer tool that cuts a versioned release: detects what consumers need, bumps the version, writes the CHANGELOG entry + Upgrade block, and stages the commit + tag for approval.
  • CHANGELOG.md and the machine-actionable ### Upgrade block format that /agent-kevin:upgrade consumes.
  • Dashboard — System → Changelog tab, plus an amber "upgrade available" sidebar badge (and a SessionStart banner nudge), driven by a local, zero-network compare of the home baseline against the installed version.
  • .kevin/version.json — the home's template baseline, git-tracked so it survives a clone/restore.

Changed

  • /init now records .kevin/version.json for fresh homes and grants the upgrade/release skills.
  • The .gitignore template now tracks .kevin/version.json (the same way it already tracks the compile cursor). For existing homes, /agent-kevin:upgrade applies this automatically.

Upgrade

  • settings: mandatory — add Skill(agent-kevin:upgrade) and Skill(agent-kevin:release) to .claude/settings.json permissions.allow.

[0.1.25] - 2026-06-19

Baseline entry — versioned release tracking begins here. Everything through v0.1.25 (the knowledge wiki, task system, dashboard, SEO/browser/database packs, worktree setup, plan-spec / simple-simplify / humanizer skills, the sync-overdue dashboard warning, path-scoped rules) shipped before this CHANGELOG existed; consult git log for that history.

Upgrade

  • none: none — None — code-only baseline, no bun install or HOME changes.

On this page

Upgrade-block format[0.4.5] - 2026-09-13AddedChangedUpgrade[0.4.4] - 2026-09-12AddedChangedUpgrade[0.4.3] - 2026-09-10ChangedFixedUpgrade[0.4.2] - 2026-09-09AddedChangedUpgrade[0.4.1] - 2026-09-07AddedChangedFixedUpgrade[0.4.0] - 2026-09-06AddedChangedUpgrade[0.3.33] - 2026-09-05FixedChangedUpgrade[0.3.32] - 2026-09-01ChangedUpgrade[0.3.31] - 2026-08-31AddedChangedUpgrade[0.3.30] - 2026-08-25FixedUpgrade[0.3.29] - 2026-08-20AddedChangedFixedUpgrade[0.3.28] - 2026-08-20AddedChangedFixedRemovedUpgrade[0.3.27] - 2026-08-17AddedChangedFixedUpgrade[0.3.26] - 2026-08-13AddedChangedFixedUpgrade[0.3.25] - 2026-08-10AddedFixedChangedUpgrade[0.3.24] - 2026-08-07AddedFixedUpgrade[0.3.23] - 2026-08-06AddedChangedUpgrade[0.3.22] - 2026-08-06AddedFixedUpgrade[0.3.21] - 2026-08-05FixedAddedChangedUpgrade[0.3.20] - 2026-08-05AddedFixedChangedUpgrade[0.3.19] - 2026-08-03AddedChangedFixedUpgrade[0.3.18] - 2026-08-03AddedChangedFixedUpgrade[0.3.17] - 2026-07-30AddedChangedUpgrade[0.3.16] - 2026-07-24AddedChangedFixedUpgrade[0.3.15] - 2026-07-24AddedChangedUpgrade[0.3.14] - 2026-07-23AddedChangedUpgrade[0.3.13] - 2026-07-16AddedUpgrade[0.3.12] - 2026-07-13AddedFixedUpgrade[0.3.11] - 2026-07-12AddedChangedUpgrade[0.3.10] - 2026-07-09AddedUpgrade[0.3.9] - 2026-07-09AddedChangedUpgrade[0.3.8] - 2026-07-09AddedUpgrade[0.3.7] - 2026-07-06FixedUpgrade[0.3.6] - 2026-07-01ChangedUpgrade[0.3.5] - 2026-06-30AddedUpgrade[0.3.4] - 2026-06-25AddedChangedUpgrade[0.3.3] - 2026-06-25AddedChangedFixedUpgrade[0.3.2] - 2026-06-24AddedChangedFixedUpgrade[0.3.1] - 2026-06-24FixedChangedUpgrade[0.3.0] - 2026-06-24AddedChangedUpgrade[0.2.9] - 2026-06-23AddedChangedUpgrade[0.2.8] - 2026-06-23FixedChangedUpgrade[0.2.7] - 2026-06-22FixedUpgrade[0.2.6] - 2026-06-21ChangedUpgrade[0.2.5] - 2026-06-21ChangedFixedUpgrade[0.2.4] - 2026-06-20ChangedUpgrade[0.2.3] - 2026-06-20AddedChangedFixedUpgrade[0.2.2] - 2026-06-20FixedChangedUpgrade[0.2.1] - 2026-06-20FixedUpgrade[0.2.0] - 2026-06-20AddedChangedUpgrade[0.1.25] - 2026-06-19Upgrade