0.302     2026-06-21 23:04:42Z

    - `karr board` now renders a compact, Markdown-flavoured plaintext board
      (board name as `#`, each status as `## Section`, one
      `- id | title | meta...` line per task) instead of the coloured column
      dashboard. The output stays clean when piped or redirected — colour is
      added only when stdout is a terminal and `NO_COLOR` is unset. Default
      (`medium`) priority is suppressed, and a new `--tags` flag prints each
      task's tags on an extra indented line.
    - Fix releasing a claim or unblocking a task leaving a null `claimed_by`,
      `claimed_at`, or `blocked` field behind. Clearing now uses real Moo
      clearers so the predicate drops and the field is omitted from the task
      file, instead of being written as an explicit null that reloaded as
      "still set" — which made `handoff` reject released tasks and `pick`
      treat them as claimed. Explicit nulls in already-written or external
      task files are normalized to "unset" on load.

0.301     2026-06-04 22:35:33Z

    - karr-foundation: stream agent output to the terminal when interactive
      (TTY detected) or --verbose is set. The parent process now reads the
      child's output through a native pipe and fans it to the log, the
      terminal, and an in-memory buffer — no external `tee` and no re-reading
      the log by byte offset. The per-run timeout is `select`-based (robust
      against Perl's deferred signals) and only fires when max_runtime > 0
      (max_runtime: 0 disables it entirely). Output is always appended to
      .karr.log regardless of TTY.
    - karr-foundation is now a multi-board coordinator, not just an agent
      runner. Agent execution is opt-in: with no agent configured on any
      board, the default action is a read-only overview of every board
      (status counts, in-progress/blocked, lock/cooldown state). `--status`
      forces that overview regardless of configuration.
    - karr-foundation: `claude: true` synthesizes the canonical claude
      invocation so you needn't retype it; `claude_bin`, `claude_max_turns`
      and `claude_permission_mode` override the parts. The agent instruction
      is exposed as the `$PROMPT` substitution variable (settable via `prompt`
      in .karr or `default_prompt` in config), usable in any command template.
    - Activity log entries are now keyed by a role-qualified identity
      (`refs/karr/log/<role>/<email>`, role `user` or `agent`) so a human and
      an AI sharing one Git config are told apart. The role propagates to
      nested karr calls via the KARR_ROLE env var (foundation sets `agent`);
      pre-existing bare-email logs are still read for the `user` role.
    - karr show: with no ID shows the single most recently updated task;
      `--last N` widens that, `--me` shows the task(s) the current identity
      most recently acted on (via the activity log), and `--agent NAME` shows
      the task(s) most recently claimed by that agent name.
    - karr board: hide the `@claimed_by` badge and claimed-count for tasks in
      a terminal status (done/archived) — a claim is an active lease, and the
      history remains in the activity log.
    - sync: surface the real libgit2 error on a failed pull/push instead of a
      meaningless "(exit code $?)" (native libgit2 operations have no shell
      exit code). New Git `last_error` accessor records the last remote-op
      exception.

0.300     2026-05-27 20:43:23Z

    - Docker: bundle libgit2 (Alien::Libgit2 share build) so the runtime
      image is self-contained. Builder installs cmake/pkg-config/zlib/
      libssh2 dev headers and sets ALIEN_INSTALL_TYPE=share; runtime-base
      installs libssl3/libssh2-1/zlib1g (the shared libs the vendored
      libgit2.so links against). Needed since Git::Native moved to
      Git::Libgit2 (libgit2 FFI).
    - Add .github/workflows/ci.yml (perl 5.36/5.38/5.40) using the
      [@Author::GETTY] dzil-test composite action; installs libgit2-dev so
      Alien::Libgit2 links the system libgit2 (>= 1.5) in CI.
    - Git.pm: read git config (user.name/email) and validate helper ref
      names through Git::Native (Config + reference_name_is_valid) instead
      of poking Git::Libgit2::FFI directly. New Git.pm `ref_oids` helper.
    - karr-foundation: detect board changes via Git::Native instead of
      shelling out to `git for-each-ref` — no git binary needed for that
      path anymore. Sync (`--pull`) and open-task detection now run
      in-process via App::karr::Git/BoardStore instead of forking the
      `karr` CLI.
    - karr-foundation: drain each board instead of a single run — invoke
      the agent command repeatedly until no actionable task (non-terminal
      and unblocked) remains. A task the agent claims but never moves is
      auto-blocked after `max_attempts` stalls (default 2) so the drain
      always terminates; the agent's own `--block` reason still wins.
      Observable common errors (non-zero/timeout exit, or a log match
      against rate-limit/auth/network/5xx patterns, extensible via
      `error_patterns`) never penalize a task and instead trigger an
      exponential per-repo cooldown (1, 2, 4, … minutes, capped). New
      `.karr` keys: `drain`, `max_attempts`, `max_iterations`,
      `cooldown_base`, `cooldown_max`, `error_patterns`.
    - cpanfile: require Git::Native 0.003 and Git::Libgit2 0.004.
    - Fix `karr context` / `karr context --json` crashing with
      "Can't locate object method 'strftime' via package 'Sun May ...'":
      Cmd::Context now `use Time::Piece`, so `gmtime` returns a
      Time::Piece object instead of a plain string. Added t/07-context.t
      covering the plain, --json, and recently-completed cutoff paths.
    - Fix `karr config show` (and get/set) crashing with
      "Can't locate object method 'board_dir'": Cmd::Config now builds
      its config via `$self->store->effective_config` and persists with
      `$self->store->save_config`, instead of calling the non-existent
      `board_dir` on itself. Added t/06-config-cmd.t.
    - Drop hard-coded `tags = latest` / `tags = user` in the Docker
      subsections so the new `[@Author::GETTY::Docker]` default
      (`latest %V %v`) applies. `runtime-user` keeps a `-user`
      suffix on each tag.
    - Add `karr-foundation` binary and `App::karr::Foundation` module:
      single-shot daemon for periodic agent execution across multiple karr
      boards. Reads `~/.config/karr-foundation/config.yml` (dirs: / scan:),
      checks each repo for board changes or open tasks, and invokes the
      per-repo `.karr` command. Supports `--force`, `--dry-run`, `--verbose`.
      Per-repo state in `.karr.state` / `.karr.lock` / `.karr.log` (gitignored).

0.202     2026-05-17 05:17:07Z

    - Fix `karr list` crashing with "Can't locate object method 'load_tasks'":
      Cmd::List was missing `with 'App::karr::Role::BoardAccess'` (the role was
      `use`d but never consumed). Surfaced while writing worktree tests.
    - Add t/29-worktree.t covering init/create/list inside `git worktree`
      directories and verifying refs/karr/* are correctly shared between the
      main work-tree and additional worktrees.

0.200     2026-05-16 17:45:23Z

    - Centralize config knowledge: priority_order(), class_order(),
      terminal_statuses(), is_terminal_status(), status_requires_claim()
      moved to Config and BoardStore (no more duplication across commands).
    - Add all_status_names(), status_requires_claim(), is_terminal_status()
      to BoardStore for encapsulated status config access.
    - Convert all require Time::Piece to use Time::Piece (Pick, Move, Edit).
    - Extract append_log into App::karr::ActivityLog module.
    - Architecture refactor: split Role::BoardAccess into Role::BoardDiscovery +
      Role::SyncLifecycle. Commands now work directly on refs via BoardStore
      instead of via a materialized temp directory.
    - Add SyncGuard (push insurance on die/croak), effective_config() on BoardStore,
      and $self->config via Role::BoardDiscovery.
    - Add tasks/ to .gitignore (never commit materialized view).
    - Fix CPAN smoker failures: skip git tests on old git (< 1.8.5, no -C flag)
    - Fix skip() without SKIP block in t/11-git-impl.t (Test::More crash)
    - Skip user.email test gracefully when not configured

0.101     2026-03-23 03:02:05Z

    - Strengthen docs and GitHub landing pages
    - Add POD to all modules (bin/karr, BoardStore, commands, roles)

0.100     2026-03-23 01:50:27Z

    - Migrate board state to git refs only (refs/karr/*), drop karr/ directory
    - Add backup and restore commands for refs/karr snapshot export/import
    - Add destroy command (remove all board refs, local and remote)
    - Add set-refs / get-refs helper commands for arbitrary ref storage
    - Add skill command with File::ShareDir-based skill loading
    - Simplify board output and drop WIP limits from config
    - Split Docker runtime images (slim + full) with entrypoint script
    - Expand POD across Git.pm, Lock.pm, commands, and roles

0.003     2026-03-20 05:01:01Z

    - BREAKING: Git sync stores task data in commit-wrapped refs (pushable/fetchable)
    - Full board sync via refs/karr/* (fetch/materialize/serialize/push)
    - Add karr log command for activity trail (per-agent NDJSON refs)
    - Add --claimed-by filter to list command
    - Add Task->from_string for ref-based loading
    - Rewrite Git.pm with safe execution (_git_cmd, no shell injection)
    - Fix write_ref to create commit-wrapped refs (blob→tree→commit)
    - Fix is_repo to work from subdirectories (git rev-parse)
    - Fix push refspec to refs/karr/*:refs/karr/*
    - Pick command uses Lock for atomic task claiming
    - Remove .gitignore manipulation from init
    - Extract sync_before/sync_after into BoardAccess role
    - Extract _parse_timeout/_claim_expired into ClaimTimeout role
    - Refactor Lock.pm to accept pre-built Git object
    - Docker: add default git identity ENV vars
    - Add karr sync command (--push, --pull)
    - Add auto-sync to write commands (create, move, edit, delete, pick, handoff, archive)
    - Add App::karr::Git for Git operations via CLI
    - Add App::karr::Lock for task locking via refs/karr/tasks/<id>/lock
    - Add Docker support (raudssus/karr on GHCR)
    - Initial release
    - Implemented archive command (soft-delete to archived status)
    - Implemented handoff command (move to review with claim, note, block/release)
    - Implemented config command (show/get/set board configuration)
    - Implemented context command (generate markdown board summary for embedding)
    - Implemented agent-name command (random two-word name generator)
    - Implemented skill command (install/check/update/show agent skills)
    - Added batch operations (comma-separated IDs) to move, edit, delete, archive
    - Added --json output to all commands (show, move, edit, delete, archive, handoff, board, pick)
    - Added --compact output to board command
    - Renamed all Command packages to CamelCase
    - Moved shared helpers (find_task, load_tasks, parse_ids) into BoardAccess role
    - Added --claude-skill flag to init for installing Claude Code skill
    - Ships skill via File::ShareDir (share/claude-skill.md)
    - Extracted --json and --compact into App::karr::Role::Output
