NAME
App::karr::Foundation - Single-shot foundation daemon — periodic agent execution across karr boards
VERSION
version 0.300
SYNOPSIS
# Typical cron entry — run every 5 minutes
*/5 * * * * /path/to/karr-foundation
# Force a run regardless of board state
karr-foundation --force
# Preview what would run
karr-foundation --dry-run --verbose
DESCRIPTION
karr-foundation is a single-shot, idempotent CLI meant to be invoked periodically (cron, systemd-timer, while-loop). It scans configured karr boards, detects changes or open work, and drains each board by invoking the configured agent command repeatedly until no actionable task remains.
Config file: ~/.config/karr-foundation/config.yml (or --config).
dirs:
- /path/to/repo1
- /path/to/repo2
scan:
- /path/to/parent-dir # finds all direct subdirs that have a .karr file
Per-repo .karr file:
command: claude -p "Use karr-coordinator agent, pick next task"
on_idle: skip # 'skip' (default) | 'always-run'
max_runtime: 1800 # seconds: per-command SIGKILL + total drain budget
drain: true # loop until drained (default) | false for single run
max_attempts: 2 # stalls on one task before auto-block (default: 2)
max_iterations: 50 # hard cap on drain iterations (default: 50)
cooldown_base: 1 # cooldown minutes at level 0 (default: 1)
cooldown_max: 64 # cooldown ceiling in minutes (default: 64)
error_patterns: # extra case-insensitive substrings → common-error
- my custom api error
Drain semantics. Each iteration runs command once, then classifies the result from what foundation can observe — exit code, board ref movement, and the run's captured output:
progress — the board changed; keep draining.
stall — a task the agent claimed / left
in-progressdid not move. That task's attempt counter is bumped; atmax_attemptsit is auto-blocked (blocked: auto-block: no progress after N attempts (foundation)) so it drops out of the actionable set and the drain can finish. The agent may always set a better reason itself withkarr edit --block; the auto-block is a fallback.common-error — a non-zero/timeout exit or a
error_patternsmatch (rate limit, auth, network, 5xx, …). No task is penalized; the repo enters an exponential cooldown (cooldown_base× 2^level minutes, capped atcooldown_max, reset on the next clean run) and is skipped until it expires.idle — the agent did nothing and grabbed nothing; stop.
All state files are gitignored: .karr.state (board hash, per-task attempts, cooldown, last error), .karr.lock, .karr.log.
SUPPORT
Issues
Please report bugs and feature requests on GitHub at https://github.com/Getty/karr/issues.
IRC
Join #langertha on irc.perl.org or message Getty directly.
CONTRIBUTING
Contributions are welcome! Please fork the repository and submit a pull request.
AUTHOR
Torsten Raudssus <getty@cpan.org>
COPYRIGHT AND LICENSE
This software is copyright (c) 2026 by Torsten Raudssus <torsten@raudssus.de> https://raudssus.de/.
This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself.