NAME
Langertha::Raider::Application - Internal application service that builds and runs a raider for a workspace
VERSION
version 0.504
SYNOPSIS
# Internal to Langertha-Raider -- no API promise.
my $app = Langertha::Raider::Application->new(
root => '/path/to/project',
engine_options => { temperature => 0.2 },
);
my $result = $app->run('Explore the repo and summarize it.');
my $raider = $app->raider; # the Langertha::Raider
DESCRIPTION
Internal module. Its interface may change without notice.
The application service the surfaces share (ADR 0002): for one workspace ("root") it reads the project config file (Langertha::Raider::Config: .raider/config.yml, else the legacy .raider.yml; below, .raider.yml stands for whichever is in use, laid over the home file ~/.raider/config.yml), picks the engine through Langertha::Raider::EngineResolver, activates the packs (Langertha::Raider::Packs, ADR 0012), compiles the mission (ADR 0004, ADR 0014), mounts the tool servers -- files (Langertha::Raider::FileTools), bash with bash_output, kill_shell and monitor (Langertha::Raider::BashTools), the cron tools in the REPL ("scheduling", Langertha::Raider::CronTools), web (Langertha::Raider::WebTools), the Perl tools (Langertha::Raider::PerlTools) when granted, the Hall tools when spawned by a Hall, the agent and send_message tools (Langertha::Raider::AgentTools, whose calls run as Langertha::Raider::Subagent) below "max_agent_depth", enter_worktree and exit_worktree (Langertha::Raider::WorktreeTools, which move the "working_root") -- and builds the Langertha::Raider that runs the raids. It keeps the registry of its subagents and background work and their notifications ("tasks", ADR 0027). It opens, creates and replays the sessions of the project ("session_store", ADR 0015) and records every run in the session's journal ("run_prompt"), handing the run's events on to the surface. It prints nothing; presentation such as the live trace belongs to the surface, see Langertha::Raider::CLI.
engine_name
Langertha engine class shortcut (e.g. 'anthropic', 'openai', 'deepseek', 'groq', 'mistral', 'gemini', 'ollama'), passed as engine. Defaults to -o engine=, then to engine: in .raider.yml, then to the first *_API_KEY environment variable found, then to 'anthropic' ("engine_name" in Langertha::Raider::EngineResolver).
engine_resolver
The Langertha::Raider::EngineResolver that picks engine, model and API key from the flags, the -o options, .raider.yml and the environment, and builds the engine.
provider
The completed provider activation of raider --provider ("activate_f" in Langertha::Raider::Provider::Activation), or none. It decides engine, model and URL; see "provider" in Langertha::Raider::EngineResolver.
model
Model identifier to pass to the engine. Defaults to model in "engine_options", then model: in .raider.yml, then the per-engine cheap default. An explicit model always wins; this is the model the engine is built with.
api_key_env
Name of the environment variable used for the current engine's API key (for display / debugging). Returns undef for engines that don't use an API key (e.g. ollama).
api_key
API key for the engine. Defaults to api_key in "engine_options", then api_key: in .raider.yml, then an engine-appropriate environment variable. An explicit api_key always wins.
mission
System prompt of the Raider, compiled from separate items (ADR 0004, ADR 0014, ADR 0019), in this order: the instructions (a generic assistant persona plus the project instructions file, "instructions"; in Claude mode the neutral "claude_base_text" instead of the persona, "claude_persona_off"); the context items of "context" (the Claude memory files, AGENTS.md of --openai, the listing of the skills as name: description -- "prompt_items" in Langertha::Raider::Context); the tool description; the active packs. Skill bodies are not in it: the model loads one with the skill tool. The tool description lists the tools of the mounted tool servers -- the same servers the engine gets -- each as name(required, [optional]) from its input schema (ADR 0005); a tool that is not mounted is not described. A mission passed to the constructor (-M) replaces the instructions item only, also across "reload_mission"; the other items, the Claude memory included, still apply. With "bare" the context items, the instructions file and all packs not switched on by --pack or /pack are left out.
bare
--bare: an isolated context. No instructions file (.raider.md, .raider/instructions.md), no layout (no Claude memory, settings or plugins, layout mode bare), no skills, no pack detection, and no packs from packs: or enabled_by_default; --pack NAME and /pack NAME still switch a pack on explicitly. What remains is the instructions (the default persona, or the -M text) and the tool description.
claude
--claude: read the Claude Code layout (ADR 0019) in every layout mode but bare, whatever the configuration says. Without it, claude: in .raider.yml (or the legacy skills: [claude]) switches it on in a raider project; a project with only Claude files is in Claude mode anyway.
context
The Langertha::Raider::Context of "root" (ADR 0019): layout mode, the Claude memory, settings and plugins, the AGENTS.md item and the skill catalogue, from "claude", claude: of the configuration, "skill_sources" and "bare". Built once; building it sets the env of the Claude settings in the process environment ("apply_env" in Langertha::Raider::Context), before any tool runs.
compile_mission
my $mission = $app->compile_mission($instructions, \@tool_servers);
my $bare = $app->compile_mission($body, \@tool_servers, memory => 0);
A mission as "mission" is built: the instructions item $instructions, the context items ("prompt_items" in Langertha::Raider::Context), the tool description of @tool_servers and the active packs. The skill listing is left out when @tool_servers has no skill tool. A subagent's mission (Langertha::Raider::Subagent) is compiled here with the agent's body as $instructions and its own tool set.
With memory => 0 (the built-ins Explore and Plan, ADR 0027 §6) the mission is only $instructions, the skill listing when @tool_servers has the skill tool, and the tool description: no Claude memory, no AGENTS.md, no packs.
working_directory => $dir names $dir in the Working directory: line of the tool description instead of "working_root" -- a subagent in a worktree of its own (ADR 0032 §2), whose mission is otherwise compiled for the caller's context.
instructions_text
my $text = $app->instructions_text;
The instructions item of the "mission": the -M text, or else the default persona with the project instructions file (.raider/instructions.md, else .raider.md) appended -- the persona alone under bare.
mounted_tools
my @tools = $app->mounted_tools;
The MCP::Tool objects of the mounted tool servers, in mount order -- what the prompt describes, the engine offers and Langertha::Raider::Skill documents.
persona_intro
The first paragraph of the default persona: who the agent is and where it runs. The command line (Langertha::Raider::CLI) says it is a CLI.
persona_turn_end
The last paragraph of the default persona: how the agent ends a turn and who answers next.
claude_persona_off
True in layout mode claude (ADR 0019 §1, no raider files, only Claude Code ones): raider acts as Claude Code would, so its own default persona (Langertha, the terse style) is not used -- the instructions item is "claude_base_text" and the CLAUDE.md memory -- and the packs switched on only by enabled_by_default stay off (see "packs"). A -M mission, --pack / packs: and a raider project that merely reads the Claude layout (claude: true, --claude) are not affected.
claude_base_text
The neutral instructions item of Claude mode, in the manner of Claude Code's own base prompt: no name, no persona, the working rules.
root
Working directory for tool operations. Defaults to the current process cwd. File tools are confined to this directory, including realpath checks for symlink escapes; bash commands inherit it as their default working directory. While the session works in a worktree the tools work in "working_root" instead.
working_root
Where the session works right now (ADR 0032 §3): the directory the file, search and shell tools (and the Perl tools when they are mounted) work in, the root of "permissions", the cwd of every hook input and the Working directory: line of the next mission compiled. It starts as "root"; enter_worktree moves it into a git worktree -- the same subdirectory of it when "root" is a subdirectory of the repository -- and exit_worktree, a new conversation and the end of the session ("close_worktree_session") move it back. Everything else stays at "root": the context and layout, configuration and settings, instructions and skills, the session store and its journals, the directory hook processes run in and CLAUDE_PROJECT_DIR.
A tool call already running finishes where it started; the next one works in the new working root. Subagents spawned meanwhile start in it ("caller_root" in Langertha::Raider::Subagent); an isolated one branches from its HEAD under head, its worktree still under the main checkout's top.
worktree_session
my $wt = $app->worktree_session;
# { path, branch, top, root, created => 1, base => '...', session => $session } or undef
The worktree enter_worktree moved the session into, while it works there: path and branch (undef for a detached HEAD), top (the main checkout), root (the "working_root"), created (made by this session, so it may be removed; else entered by path and only ever left), base (the commit a created one branched from) and session (the session it was entered in, which its worktree.exited goes to).
allowed_commands
Optional arrayref restricting which bash commands may run (first word match). When undef, any command is allowed.
max_iterations
Maximum tool-calling iterations per raid. Defaults to 10_000 — effectively unlimited, so a raid only ends when the model itself stops emitting tool calls. The conversation history is preserved between raids, so the next user message in the REPL simply continues the same thread.
Set this to a smaller number if you want a hard safety cap.
max_agent_depth
How deep subagents may nest (ADR 0020 §4, ADR 0027 §8): the main run has depth 0, its subagents depth 1, and a run at this depth gets no agent tool. From max_agent_depth of the configuration (or -o max_agent_depth=), a non-negative integer -- 0 mounts no agent tool at all; else, in the Claude layout only, from CLAUDE_CODE_MAX_SUBAGENT_SPAWN_DEPTH of the environment (the Claude settings env included, "apply_env" in Langertha::Raider::Context), a positive integer; else 3, Claude Code's "up to three layers below the main conversation". 1 turns nesting off. A value that does not fit is ignored, and config explain lists it under ignored.
max_concurrent_agents
How many subagent runs of the application may run at once (ADR 0027 §9) -- all depths, foreground and background, resumed ones too; a spawn or a send_message resume beyond it is refused with an error result that tells the model not to retry now. From max_concurrent_agents of the configuration (or -o max_concurrent_agents=), a positive integer; else, in the Claude layout only, from CLAUDE_CODE_MAX_CONCURRENT_SUBAGENTS of the environment (the Claude settings env included), a positive integer; else 20, as Claude Code. A value that does not fit is ignored, and config explain lists it under ignored.
agent_models
The model per alias for agent files (ADR 0020 §5), from the mapping agent_models of the configuration, e.g. { sonnet => 'claude-sonnet-4-6' }; overrides "model_aliases" in Langertha::Raider::Context::Agents per alias. Defaults to none.
worktree_base_ref
my $mode = $app->worktree_base_ref; # 'fresh' or 'head'
Where a new worktree branches from (ADR 0032 §2): worktree.baseRef of the Claude settings in the Claude layout ("worktree_base_ref" in Langertha::Raider::Context::Settings), else worktree_base_ref of the configuration. head is the HEAD of the caller's working root; fresh -- the default, and what any other value counts as -- is origin/HEAD when it resolves, else that HEAD ("base_ref" in Langertha::Raider::Worktree).
worktrees_dir
my $dir = $app->worktrees_dir($top); # /repo/.claude/worktrees
The directory under the main checkout $top that raider's worktrees live in (ADR 0032 §2): .claude/worktrees in the Claude layout, else .raider/worktrees.
note_meta
$app->note_meta('agent agent_1 left its worktree /repo/.raider/worktrees/agent-1 on branch worktree-agent-1');
Queues a line for the person, outside any run: a surface shows it as a meta line ("take_meta_notes"). An isolated subagent cancelled without a notification names its kept worktree this way (ADR 0032 §2).
take_meta_notes
say_meta($_) for $app->take_meta_notes;
Takes the lines "note_meta" queued, oldest first.
leaving
True once "stop_background" ran: the person is leaving raider, and the notifications of the subagents that end now reach nobody.
on_event
Optional code reference called as $on_event->($type, %payload) for every event of the application ("event"): the run events of "run_prompt" and every tool.call and tool.result of a raid, which come from Langertha::Raider::Plugin::Events. A surface that follows one run passes its consumer to "run_prompt" instead.
on_journal_error
Optional code reference called as $on_journal_error->($session, $error) when an event cannot be written to a session journal (a full disk): once per run, and once per "record". The run goes on. Without it the error is a warn.
on_ask_user
Optional code reference a surface sets when a person can answer the model during a run: called as $on_ask_user->($question, \@options), it puts the question to the person and returns the answer as text (undef: none). It makes the ask_user tool work (Langertha::Raider::AskTools); the REPL sets it. Without it -- a one-shot run, the Hall, a cron job, ACP -- the tool refuses with a plain error result and the model decides itself. Read when the tool is called, so a surface may set it after the application is built.
on_permission_request
Optional code reference a surface sets when a person can approve tool calls during a run (the REPL does): called as $on_permission_request->(\%request) for every call "permissions" asks about, with tool, source, arguments, reason (why it asks) and rule (the rule "yes, for this session" would allow, undef when none can name the call safely). It returns { answer => 'once' }, { answer => 'session' } or { answer => 'no', reason => $why } (undef counts as no). "once" runs this exact call (an Langertha::Raider::Approval bound to session, run, tool, arguments and policy revision); "session" adds rule as a session rule; "no" refuses it, and the model gets the reason. Without it every such call is refused. Read for every call, so a surface may set it after the application is built.
on_plan_review
Optional code reference a surface sets when a person can review a plan: called as $on_plan_review->($plan) when the model calls exit_plan_mode in plan mode; returns { approve => 1 } (the mode becomes default) or { approve => 0, feedback => $text }. Without it the model is told to give the plan as its final answer.
permission_mode
The permission mode chosen for this application (ADR 0021): default, acceptEdits, auto, plan or bypassPermissions. It wins over permissions.default_mode of the config files and defaultMode of the Claude settings. Croaks on construction with any other name. The command line sets it with --permission-mode.
skip_permissions
True: the mode is bypassPermissions -- every tool call runs unless a deny rule refuses it. The command line sets it with --dangerously-skip-permissions. Not together with "permission_mode".
permissions
The Langertha::Raider::Permissions of the application: the mode (from "skip_permissions", "permission_mode", permissions.default_mode of .raider/config.yml then ~/.raider/config.yml, defaultMode of the Claude settings, else default), the rules of the config files ("permissions" in Langertha::Raider::Config) and, in the Claude layout, of the settings ("permissions" in Langertha::Raider::Context::Settings), and their additional directories. Every tool call of the raider passes it (the gate of ADR 0005): a call it asks about runs only when a person approves it, and without anyone to ask it is refused with a reason that says how to allow it. Its root is the "working_root", and while that is a worktree it refuses edits into the main checkout ("worktree_isolation" in Langertha::Raider::Permissions, ADR 0032 §3).
set_permission_mode
my $from = $app->set_permission_mode( 'acceptEdits', '/permissions' );
$app->set_permission_mode( 'plan', 'enter_plan_mode', call => 'c3' );
Switches the mode of "permissions" (croaks on an unknown mode) and emits permission.mode with from, to, why and the given call (the id of the tool call that switched it, ADR 0034). Returns the previous mode.
reload_permissions
$app->reload_permissions;
Reads the permission sources again (/reload): the rules, modes and additional directories of the config files and the Claude settings. The session rules stay, and so does a mode switched during the session (/permissions mode, exit_plan_mode). The mounted file and search tools read the additional directories from the policy on every call, so a directory added or removed in the sources is reachable or refused from the next call on.
tool_gate
my $raider = Langertha::Raider->new( ..., _tool_gate => $app->tool_gate );
# a sub-run (a subagent) with its own policy, journal and binding:
my $gate = $app->tool_gate(
policy => $app->permissions->for_subrun,
on_event => sub { my ( $type, %payload ) = @_; ... },
binding => sub { ( session_id => $id, run_id => $run ) },
unattended => sub { $in_background ? 'this agent runs in the background' : undef },
);
The gate every raider of the application gets (the _tool_gate of Langertha::Raider, ADR 0005): "permissions" decides each tool call. A raider built on the application's engine -- the prompt builder, a subagent -- takes it too, so no tool call passes without it.
A sub-run passes its own policy (a Langertha::Raider::Permissions, usually "for_subrun" in Langertha::Raider::Permissions of the caller's), on_event for the permission.* events (default "event") and binding, the session and run ids an approval of a call is bound to (default the run in progress). A call the policy asks about goes to the same "on_permission_request": the person at the keyboard answers for the sub-run too, and "for this session" lands in the session rules the policies share. unattended is asked at every such call: a reason (a background subagent, ADR 0027 §3) means nobody is asked, and the call is refused as in a run nobody can approve, with that reason.
Before any rule or mode, a policy with "worktree_isolation" in Langertha::Raider::Permissions refuses edits into the main checkout (ADR 0032 §3): the result is "main_checkout_refusal" in Langertha::Raider::Permissions's text as it stands, with permission.denied (by worktree).
hooks
The Langertha::Raider::Hooks runner of the Claude layout (ADR 0022): the hooks of the Claude settings and of the enabled plugins, on "loop", with "rule_matches" in Langertha::Raider::Permissions for their if rules. undef outside the Claude layout -- a native or bare run runs no hooks. /reload builds it again.
tool_hook
my $raider = Langertha::Raider->new( ..., _tool_hook => $app->tool_hook );
# a sub-run (a subagent): its own input fields, events and stop
my $hook = $app->tool_hook(
input => sub { ( agent_id => $id, agent_type => $name ) },
on_event => sub { my ( $type, %payload ) = @_; ... },
on_stop => sub { $subagent->cancel },
);
The tool hook every raider of the application gets in the Claude layout (the _tool_hook of Langertha::Raider): the PreToolUse hooks, before the inputSchema check and "tool_gate". A deny (or exit 2) refuses the call with the hook's reason; updatedInput replaces the arguments (translated back to raider's names); an allow or ask goes on to the gate, which weighs it against the rules and the mode (deny and ask rules always hold; allow only spares the mode's question; ask asks even where a rule allows). The additionalContext is appended to the tool's result.
A sub-run passes input, a code ref whose pairs go into every hook input (a subagent's agent_id, agent_type and permission_mode), on_event for the hook.ran and hook.message events (default "event") and on_stop, called on a continue: false (default "cancel_run").
note_history_cleared
$app->note_history_cleared; # /clear
The conversation starts over: the next run fires SessionStart again with source clear, and the task list ("todos") is empty. The background subagents of the conversation are stopped without a notification and the notifications that wait for it are dropped (ADR 0027); background shells go on and still notify (ADR 0024). A worktree session ends ("close_worktree_session" with clear, ADR 0032 §5). /clear, /reset and /new call it.
stop_hook_limit
How many times in a row Stop hooks may keep one run going: 8, Claude Code's cap. The next block is overridden and the run ends.
shutdown_hooks
$app->shutdown_hooks;
Stops the async hooks still running and waits until they are gone ("shutdown" in Langertha::Raider::Hooks), as Claude Code does when a -p run ends. The command line calls it when it is done.
configured_mcp
The configured MCP servers of the application (ADR 0029), a Langertha::Raider::MCP over "from_context" in Langertha::Raider::MCP::Config of "context" and "config". Its clients lead the engine's mcp_servers; "raid_f" starts them (in parallel, never failing) before the first raid; the permission gate knows them as foreign servers. Each start that ends emits mcp.server (name, scope, transport, status connected or failed, reason, tools, the number of tools); so does each start (starting) and stop (stopped), and mcp.tools_changed (name, scope) a server's tools/list_changed. Inside a run they are in the session journal. Stopped by "shutdown_mcp".
shutdown_mcp
$app->shutdown_mcp;
Stops the configured MCP servers and waits until they are gone (a stdio process: stdin closed, then TERM, then KILL). The command line calls it when it is done.
reload_mcp
$app->reload_mcp;
Reads the MCP configuration again (/reload, after "reload_context" read the config files and settings): a server configured exactly as before keeps its running connection, the others are stopped and the new ones start with the next raid. The front of the engine's mcp_servers and the policy's source_servers change in place. Nothing to do before the servers were first needed.
reconnect_mcp
my @names = $app->reconnect_mcp('github'); # or 'all' / undef
Stops the named configured server (every one with all or no name) and starts it again at once, in the same place; waits for the start. Returns the names restarted (none for an unknown name).
mcp_pids
The process ids of the running stdio servers; a cancelled run leaves them alone ("cancel_run" in Langertha::Raider::CLI::Runner).
mcp_notes
The lines "notes" in Langertha::Raider::MCP gives: the project servers that wait for an approval nobody can give in this run. The command line prints them on stderr.
ask_mcp_approvals
$app->ask_mcp_approvals(sub {
my ( $server ) = @_; # an entry of Langertha::Raider::MCP::Config/servers
return 'approve'; # or 'all', 'reject', undef (no answer: stays pending)
});
Puts every pending project server to the person once (ADR 0029 §7), writes each answer where it counts next time ("record_approval" in Langertha::Raider::MCP::Config), and makes it hold now ("reload_mcp"). After all nobody is asked again. Returns a list of { name, answer, written } (written: the file's label, or undef when it holds for the session only).
mcp_report
my $r = $app->mcp_report;
The configured MCP servers for config explain and /mcp: servers ("report" in Langertha::Raider::MCP), errors (files that could not be read), warnings (MCP_TIMEOUT / MCP_TOOL_TIMEOUT), trust (with its source), approvals_go_to (where an answer is written) and the startup_timeout_ms / tool_timeout_ms.
mcp_prompts
for my $p (@{ $app->mcp_prompts }) { say $p->{command}, ' ', $p->{description} }
The prompts of the connected configured MCP servers as slash commands (ADR 0029 Addendum 1): command (mcp__SERVER__PROMPT, the server part as in tool names, the prompt name as the server declares it), server, name, description and arguments (the server's list, each name, required). Starts nothing -- a server that is not connected has none.
mcp_prompt_request
my $request = $app->mcp_prompt_request( 'mcp__github__pr_review', '456' );
# { prompt => ... } or { error => '...' }, nothing for a name that is no MCP prompt
A /mcp__SERVER__PROMPT ARGS run (ADR 0029 Addendum 1): starts the configured servers when they are not yet, finds the prompt on the server whose tool-name part is SERVER, maps the whitespace-separated arguments on the prompt's declared arguments in order, asks the server (prompts/get) and frames the messages as a run request, in the framing of a custom command (ADR 0030 §3):
<command-message>mcp__github__pr_review is running...</command-message>
<command-name>/mcp__github__pr_review</command-name>
<command-args>456</command-args>
MESSAGE TEXTS
Every message becomes part of one user prompt, in order, text only: a resource inside a message contributes its text, an image or other content a note. A missing required argument, one too many and a failing prompts/get are an error.
loadguard
The Langertha::Raider::Loadguard that gates bash: a heavy command (prove, dzil test, cpanm, podman run ...) is refused with the reason while the host is out of memory or the heavy slots are taken. Built from the environment (LOADGUARD_*) unless given.
bash_tools
The Langertha::Raider::BashTools behind bash, bash_output, kill_shell and monitor, built once with "root", "allowed_commands", the "loadguard" gate, "loop" and "tasks". Its background shells belong to the application: they live across the runs of a session and are stopped when the application goes away. They are entries of "tasks" (bash_N) and notify the run that started them when they end; bash_output and kill_shell reach the subagents there too (ADR 0027 §10).
perl
Enable the PerlTools MCP server (perl_eval, perl_check, perl_cpanm). Off by default; set via --perl CLI flag or perl: true in .raider.yml. Without either, the tools also come with the perl pack, which is detected in a Perl workspace; see "perl_tools_enabled".
perl_tools_enabled
Whether the PerlTools server is mounted: --perl turns it on; else an explicit perl: (in .raider.yml or -o perl=) decides either way; else it is on when an active pack requests the perl tools (the bundled perl pack, detected by cpanfile, dist.ini, Makefile.PL or lib/**/*.pm). Granting a pack's request here stands in for the local tool policy of ADR 0005, which does not exist yet; perl: false is the local denial. A pack switched on or off later is followed by "reload_mission", which remounts the server to match.
perl_tools_grant
my $grant = $app->perl_tools_grant;
# { enabled => 1, reason => 'pack perl (detected)' }
"perl_tools_enabled" with the reason: "perl" by its "source_label" (--perl on the command line), perl: true or perl: false with where it was set (.raider.yml or the label of engine_options, -o), the active packs requesting the tools with their activation source, or not requested.
preferred_lib_target
Override the default local::lib target for perl_cpanm. When unset, defaults to .raider/lib/ for standalone raiders. Can be set via preferred_lib_target in .raider.yml.
pack_names
Optional list of pack names supplied by the CLI, usually from repeatable --pack NAME. When present, these override the packs: list in .raider.yml.
no_pack_names
Pack names switched off from the command line (repeatable --no-pack NAME). They win over --pack, packs:, the bundled defaults and detection.
detect
Pack detection from the command line: 0 for --no-detect, 1 for --detect. When not given, detect: in .raider.yml decides; the default is on.
packs
Langertha::Raider::Packs::Collection of the installed packs: those in "root"/.raider/packs/, ~/.raider/packs/, the bundled share/packs/ and $RAIDER_PACK_DIRS, the first place winning for a name ("build_packs" in Langertha::Raider::Packs). Which are enabled, highest priority first (ADR 0012); with "bare" only --pack NAME applies:
- 1.
--no-pack NAMEswitches a pack off;--pack NAME(or-o packs=a,b) enables the listed ones exclusively;--no-detect/--detectswitch detection off or on. - 2.
packs:in .raider.yml ([caveman, git-guru]) enables the listed ones exclusively when no flag named packs;detect: falseandno_detect: [NAME]switch detection off entirely or per pack. - 3. Packs whose detection rule matches "root" are added.
Without explicit packs the bundled defaults (enabled_by_default) are on -- except in Claude mode ("claude_persona_off"), where no pack is on merely by default; config explain shows them as switched off by the layout.
Detection rules come from a pack's pack.yml (detect:, the pack default) and from detect: in ~/.raider/config.yml and .raider.yml, which replace the pack default per pack name, the project's rule over the home's. Each rule is evaluated against "root" with Langertha::Raider::Detect when "packs" is built and on "redetect_packs" (/reload), never per model call. A detected pack is added to the enabled ones; in an exclusive group it gives way to an explicit pack and replaces a bundled default. The outcome per pack is in "activation_report" in Langertha::Raider::Packs::Collection. An invalid rule croaks.
Detection only decides which packs are active, it grants nothing (ADR 0005). Rules from the project's .raider.yml or .raider/config.yml are evaluated and packs from its .raider/packs/ are loaded right away: the workspace trust decision of ADR 0004, which is meant to gate both, does not exist yet.
detection_state
my ( $on, $why ) = $app->detection_state;
Whether pack detection runs, and what decided it: "bare" or "detect" by their "source_label" (--bare, --detect, --no-detect on the command line), detect: false or default.
redetect_packs
my @detected = $app->redetect_packs;
Drops the packs that were enabled by detection, evaluates the rules again against "root" and returns the names of the packs detected now. Packs enabled any other way stay as they are. /reload calls it.
max_context_tokens
Trigger history auto-compression once the last prompt exceeds context_compress_threshold * max_context_tokens. Defaults to 40_000, which keeps the running session comfortably under typical per-minute rate limits (Anthropic org default: 50k input tokens/min on Haiku).
context_compress_threshold
Fraction of "max_context_tokens" at which compression kicks in. Defaults to 0.7.
skill_sources
ArrayRef of the explicit skill directories, the first skill roots of "context" (ADR 0019 §4). Each spec is a hashref:
{ type => 'claude', path => 'some/skills' } # */SKILL.md skill directories
{ type => 'dir', path => 'my-skills', glob => '*.md' } # flat *.md skills
{ type => 'dir', path => 'my-skills' } # both
Defaults to the skills entries of .raider.yml (see "normalize_skill_spec" in Langertha::Raider::Config), then -o skills=, then "cli_skill_sources". Passing skill_sources explicitly replaces them. With "bare" there are none. The skills are listed in the mission and loaded by the model with the skill tool, not glued in.
cli_skill_sources
ArrayRef of skills: items from the command line: openai for --openai / --codex (AGENTS.md as an instructions item) and { type => 'dir', path => DIR } for each --skills DIR. They are added to the .raider.yml skills, duplicates dropped. --claude is "claude".
config
The Langertha::Raider::Config of "root": .raider/config.yml, else .raider.yml, over ~/.raider/config.yml.
instructions
The Langertha::Raider::Instructions of "root": the project instructions file, .raider/instructions.md, else .raider.md.
engine_options
HashRef of the -o KEY=VALUE options. Engine attributes (e.g. temperature, response_size, seed) are forwarded to the engine constructor, merged on top of values loaded from .raider.yml in the working directory. Raider's own keys (see "is_app_key" in Langertha::Raider::Config) configure raider like their .raider.yml counterparts and override them; packs and skills take a comma-separated list.
worktree_class
The class that does the git work of enter_worktree and exit_worktree: Langertha::Raider::Worktree.
worktree_tools_class
The class with the two tools' texts and schemas: Langertha::Raider::WorktreeTools.
close_worktree_session
$app->close_worktree_session('clear'); # /clear, /reset, /new
$app->close_worktree_session('session_end'); # leaving the REPL, the end of raider -p
Closes the worktree session at a new conversation or the end of the session (ADR 0032 §5), as exit_worktree would, without asking: a worktree enter_worktree created is removed with its branch when it has no changes, and kept otherwise, with a meta line ("note_meta": worktree P kept on branch B (has changes), or the reason git gave); one entered by path is only left. The "working_root" is back at "root"; worktree.exited has reason clear or session_end. Nothing without a worktree session. Never dies.
subagent_class
The class that runs a call of the agent tool: Langertha::Raider::Subagent.
tasks
The application's Langertha::Raider::Tasks (ADR 0027 §1): the registry of its subagents (agent IDs agent_N) and background work, and the queue of their notifications, built on first use over "loop".
web_fetch_engine
The engine that answers the prompt of web_fetch (ADR 0026): the run's own engine, or -- with web_fetch_model in the config (.raider/config.yml, the engine's section, -o web_fetch_model=) -- the same engine, provider and key with that model, e.g. a smaller one. Built when first needed.
scheduling
Bool, default false. True when the surface runs scheduled prompts as turns of their own while it is idle -- the REPL does (ADR 0031): only then are cron_create, cron_delete and cron_list mounted. A run with a single prompt, a Hall raider and ACP have no idle state a prompt could be run in, so they are not offered the tools, and Claude Code's CLAUDE_CODE_DISABLE_CRON=1 turns them off in the REPL too. Set it before the tools are first used (the engine is built).
cron_tools
The Langertha::Raider::CronTools behind the cron tools, built once over "loop" and "tasks". Its jobs belong to the application: they are entries of "tasks" (cron_N) and go when it does.
caller_event
$app->caller_event($session, 'agent.finished', agent_id => 'agent_1', ...);
An event of a subagent of the main run for its caller: "event" while a run is in progress (the run that is current, ADR 0027 §3); between runs -- a background agent that ends while the REPL waits -- appended to $session (the session the agent was started from, when it is still open) for the types the journal records, and handed to "on_event".
background_running
my $n = $app->background_running;
How many background subagents and monitors of the main run still run. A monitor ends at its deadline (at most 10 minutes in a run with a single prompt, ADR 0031), so a run that waits for it waits for a bounded time. Background shells do not count: nothing waits for them (ADR 0024, a server may run for the whole session); their notifications are delivered when they come.
scheduled_pending
How many prompts of due cron jobs wait for the surface to run them (ADR 0031).
take_scheduled
my @items = $app->take_scheduled; # ( { text, id, label, scheduled }, ... )
Takes the prompts of due cron jobs, oldest first: for the surface that runs each as a turn of its own when it is idle (the REPL).
idle_pending
How many notifications and scheduled prompts wait for an idle surface.
idle_wait_f
$app->loop->await( $app->idle_wait_f );
A future that is done once something waits for an idle surface ("idle_pending"). Cancelling it is fine.
notifications_pending
How many notifications wait for the main conversation (ADR 0027 §4).
take_notifications
my @items = $app->take_notifications; # ( { text, notification, id, label }, ... )
Takes the notifications that wait for the main conversation, in the order their work ended: for a surface that delivers them itself (the REPL).
wait_for_notifications
my $n = $app->wait_for_notifications;
Runs the loop until a notification waits for the main conversation or no background subagent of it runs any more; returns how many wait.
stop_background
my $n = $app->stop_background;
Leaving raider (ADR 0027 §3): asks every subagent of the application that still runs to end ("stop_all" in Langertha::Raider::Tasks) and runs the loop until they have, at most $grace seconds (default 2), so their journals end. Returns how many it stopped. The application is "leaving" from then on.
slash_command_class
Langertha::Raider::SlashCommand, the renderer of /name and the skill tool.
slash_renderer
my $renderer = $app->slash_renderer( session => $session );
A Langertha::Raider::SlashCommand over "root" with the application's "permissions", the loadguard gate ("loadguard") and the session's id for ${CLAUDE_SESSION_ID}; disable_shell is the Claude settings' disableSkillShellExecution ("disable_skill_shell_execution" in Langertha::Raider::Context::Settings). The additional directories come from the policy.
slash_run_request
my $request = $app->slash_run_request( 'review', 'src/App.pm', session => $session );
# { prompt => ..., allow_rules => [...], allow_source => '/review allowed-tools',
# model => 'sonnet', attach_reads => [...] } or { error => '...' }
$app->run_prompt( $request->{prompt}, %$request, session => $session ) unless $request->{error};
A /NAME REST run of a user-invocable catalogue entry (ADR 0030 §3): the entry (a name, or the entry hash) rendered with the arguments and @file attachments ("slash_renderer"), then framed as Claude Code frames it (the ... is one character, U+2026):
<command-message>NAME is running...</command-message>
<command-name>/NAME</command-name>
<command-args>REST</command-args>
RENDERED TEXT
The rest is what "run_prompt" takes for that run: the entry's allowed-tools as allow_rules with their allow_source, its model frontmatter (when set) and the attached files as attach_reads. A render that aborts gives { error => $reason }; nothing is to be sent then. session may be a code reference, called only when an entry is rendered. Returns nothing for a name that is no user-invocable entry.
skill_tool_text
my $loaded = $app->skill_tool_text( $entry, $args ); # { text } or { error }
What the skill tool loads for a model-invoked entry (ADR 0030 §2): the body rendered with the arguments and its !`cmd` (through the permission policy, nobody asked), without @file attachments. When it renders and a run is in progress, the entry's allowed-tools hold for the rest of that run ("add_run_rules" in Langertha::Raider::Permissions). Its model is ignored: the engine is not switched inside a run.
resolve_run_model
my $resolved = $app->resolve_run_model('sonnet'); # { model => '...' } or { inherit => 1, reason => ... }
The model of a /name run as a subagent's is resolved (ADR 0020 §5, "resolve_model" in Langertha::Raider::Context::Agents): an alias or a claude-* id under the Anthropic API, "agent_models" applied; inherit, empty or anything else keeps the engine's model.
file_read_state
The record of the files read in the run in progress (Langertha::Raider::FileTools::ReadState), which the file tools hold write_file, edit_file and multi_edit against: an existing file must have been read in this run, and not changed on disk since (ADR 0023). "begin_run" empties it and then records the instructions files of the prompt (CLAUDE.md, AGENTS.md, ...) as read. A surface that shows the model a file's content itself (the prompt builder) records it here.
task_tools
Which task-list family the application mounts (ADR 0025), one of the two of Langertha::Raider::TodoTools, as Claude Code offers one: true (the default) for task_create, task_update, task_list and task_get (Claude Code's TaskCreate & co.), false for todo_write (TodoWrite). Defaults to RAIDER_ENABLE_TASKS when set (0 or false turns the task tools off, like Claude Code's CLAUDE_CODE_ENABLE_TASKS).
todos
my $list = $app->todos; # [ { content, status, activeForm, ... }, ... ]
The task list, as the model last left it (Langertha::Raider::TodoTools): a copy; empty when the model kept none. With "task_tools" it is the list of task_create & co., kept for the conversation: runs go on with it, "note_history_cleared" (/clear) empties it. With todo_write it is state of the run: "begin_run" empties it. Every change is the event todo.updated with the whole list as todos, which the session journal records.
build_subagent_engine
my $engine = $app->build_subagent_engine(mcp_servers => \@clients, model => $model);
The engine of a subagent (Langertha::Raider::Subagent): the class and arguments of the main engine ("build_engine" in Langertha::Raider::EngineResolver) over the subagent's own MCP clients, on the same loop. model replaces the model when given; without, the subagent inherits it. The one place a subagent's engine comes from, so a subclass (or a test) can swap it.
note_usage
$app->note_usage(model => 'claude-haiku-4-5', input_tokens => 1200,
output_tokens => 80, cache_read_tokens => 1000);
Adds one model call to the token ledger of the application (ADR 0026): cumulative, per model, over every raider of it -- the main one, its subagents and a tool's own model calls. cache_read_tokens and cache_write_tokens are part of input_tokens as the engine reports them. The model.usage events of every raider's Langertha::Raider::Plugin::Events and of web_fetch reach it; a surface does not need to call it.
usage_stats
my $u = $app->usage_stats;
# { input_tokens, output_tokens, cache_read_tokens, cache_write_tokens,
# calls, models => { $model => { same keys } } }
The token ledger ("note_usage") as a copy: the totals and the same counts per model; zeros and no models before the first model call. This is what /stats shows and the usage of the metrics of a run.
run_plugins
my @plugins = $app->run_plugins(sub { my ( $type, %payload ) = @_; ... });
my @plugins = $app->run_plugins($on_event, input => sub { ... }, on_stop => sub { ... });
The plugins every raider of the application runs with, as name + {args} pairs for "plugins" in Langertha::Raider, with $on_event as the consumer of Langertha::Raider::Plugin::Events. The main raider's consumer is "event"; a subagent passes its own, so its events go to its journal only. A surface's own plugins (the live trace) are not part of it. In the Claude layout Langertha::Raider::Plugin::ClaudeHooks reports its hooks to $on_event too, and gets input and on_stop as "tool_hook" does.
session_embeddings
my $grant = $app->session_embeddings; # { enabled => 0, reason => ... }
Whether the raider embeds its session history ("no_session_embeddings" in Langertha::Raider, ADR 0028): only when a tool that reads the vectors, session_history or raider_session_history, is mounted. The application mounts none, so each message would cost an embedding request nothing uses -- noise, cost and, with a provider without an embeddings endpoint, a 404. reason says why it is off. Whether the engine can embed is decided by the raider.
raid_f
my $result = await $app->raid_f($prompt);
Async variant: drives one raid iteration and returns the Langertha::Raider::Result.
run
my $result = $app->run($prompt);
Synchronous convenience wrapper around "raid_f". Runs the I/O loop until the raid completes and returns the result (which stringifies to the final text).
run_prompt
my $outcome = $app->run_prompt($text,
session => $session, # optional
on_event => sub { my ( $type, %payload ) = @_; ... }, # optional
# optional, for one run only (see begin_run):
allow_rules => \@rules, allow_source => $source, model => $model, attach_reads => \@files,
notification => 1, # $text is a notification (ADR 0027)
reminders => $blocks, # notifications in front of $text
wait_background => 1, # a run that ends waits for its background agents
);
Runs $text as one run ("run") and records it, whichever surface asks; the run options of "begin_run" (a /name run's allowed-tools, model and attached files, "slash_run_request") hold for this run only. It is recorded: in the journal of the Langertha::Raider::Session as the session's next run (ADR 0015) -- run.started, the user input as message, every tool.call and tool.result with the whole result text (and after it a user message a result hands the raid, such as a loaded skill, ADR 0026), the tokens of a model call a tool makes as model.usage (purpose, model, input_tokens, output_tokens; web_fetch with a prompt), the final answer as message, and run.finished with the end state and the raider's metrics, also when the run failed. A journal write that fails goes to "on_journal_error"; the run goes on.
Every event of the run goes to on_event (and "on_event") through "event": the journal types and run.state (running, then the end state), as ADR 0013 names them.
In the Claude layout the run fires the Claude Code hooks ("hooks", ADR 0022): SessionStart before the first prompt of a session, the results of async hooks and UserPromptSubmit before every prompt -- their context goes in front of the prompt as <system-reminder> blocks; a block ends the run failed with the reason, and the model never sees the prompt -- and Stop after the answer: a block sends its reason back as the next user message, at most "stop_hook_limit" times. Every hook is a hook.ran event, a systemMessage, a hook error or a stop a hook.message.
Background subagents (ADR 0027 §3, §4): the notifications that are due when the raider is about to ask the model again go in front of that request as a user message (journaled as message with notification 1). notification marks $text itself as such a message (a REPL turn that only delivers notifications; it runs no UserPromptSubmit). reminders -- notifications wrapped for a turn of the user's ("reminder_text" in Langertha::Raider::Tasks) -- go in front of the prompt and are journaled before it as a message with notification 1. With wait_background a run that would end while background subagents of the main run still run waits for them on the loop and goes on with their notifications as its next message, until an answer leaves none (raider -p, the end of piped REPL input); a "cancel_run" ends the wait as cancelled.
Returns the outcome as a hash reference: status (completed, failed, or cancelled after "cancel_run"), elapsed (seconds, to the millisecond), result (the Langertha::Raider::Result, also of a cancelled run), response (its text) and metrics of a completed run, error of a failed one, reason of one that did not complete (see "end_run"; a failed run says run_setup when "begin_run" croaked, hook_blocked or hook_stopped when a UserPromptSubmit or SessionStart hook blocked or stopped it, max_iterations or engine_error when the raid ended so, else error), and session (id, path) when there is one. An empty $text runs nothing and returns nothing.
is_journal_type
$app->is_journal_type('tool.call'); # 1
Whether the journal records events of that type from a run (ADR 0015): run.started, message, tool.call, tool.result, todo.updated, the permission.* events (ADR 0021), hook.ran and hook.message (ADR 0022), agent.started and agent.finished of the subagents it starts and agent.warning about them (ADR 0020), model.usage of a tool's own model call (web_fetch's prompt, ADR 0026), mcp.server and mcp.tools_changed of the configured MCP servers (ADR 0029), worktree.entered (path, branch, created) and worktree.exited (path, branch, removed, reason exit_worktree, clear or session_end) of the "working_root" (ADR 0032 §6), outside a run into the session the worktree was entered in. run.finished is written by "end_run".
begin_run
$app->begin_run(session => $session, on_event => $consumer);
# a /name run (L</slash_run_request>):
$app->begin_run(session => $session, allow_rules => [ 'Bash(git diff:*)' ],
allow_source => '/review allowed-tools', model => 'sonnet', attach_reads => \@files_read);
Starts a run as "run_prompt" does, for a surface that drives "run" itself: the run gets the next run id of session, run.started and run.state running. run.started names engine and model, with a session its id (session) and the run id (run), cwd (the "working_root"), permission_mode, tools -- the names the model is offered, in order; left out while a configured MCP server has not connected yet, as before the first raid, since "raid_f" starts them -- and raider_version (ADR 0034). "end_run" ends it. When the "working_root" moved since the mission was compiled, the mission is compiled again first ("reload_mission"), so it names the new working directory.
The options of one run (ADR 0030 §3), all undone by "end_run":
allow_rules,allow_source-- allow rules for this run only ("add_run_rules" in Langertha::Raider::Permissions; source defaultrun). Deny and ask rules still win. "end_run" clears every run rule, also those theskilltool added during the run.model-- the model of this run, resolved by "resolve_run_model": when it names one, the raider runs on an engine with that model ("build_subagent_engine" over the application's MCP clients) andrun.startednames it; "end_run" puts the engine back. Never saved.attach_reads-- thefiles_readof a render ("render" in Langertha::Raider::SlashCommand): counted as read for read-before-write, after the read state was emptied for the run.
Croaks when the engine for model cannot be built; the run is begun by then, so "run_prompt" ends it failed.
end_run
my $end = $app->end_run(interrupted => signal => 'TERM');
Ends the run in progress, if there is one: run.finished with $status, reason and the given error and signal into the journal, with the given metrics or else the raider's, then run.state with $status. reason (ADR 0034) is set whenever $status is not completed: the reason given, else for cancelled the one "cancel_run" recorded (default user_cancel), else error for failed, signal for interrupted, refused for refused. It clears the run rules of the policy and puts back the engine a run model replaced ("begin_run"), whatever the status. Returns status, reason, elapsed, the error and signal given and, with a session, session (id, path) -- or nothing outside a run. A surface calls it for a run it ends itself, as the command line does for a signal.
cancel_run
$app->cancel_run;
$app->cancel_run( reason => 'hook_stopped' );
Cancels the run in progress (ADR 0009): its raid stops at the next safe point ("cancel" in Langertha::Raider) and "run_prompt" ends the run as cancelled -- run.finished with that status, and a tool call cut off gets its tool.result with status cancelled. Every foreground subagent running for it (Langertha::Raider::Subagent) is cancelled too, with the subagents it started, and its agent call ends with an error result. Background subagents keep running (ADR 0027 §3; "stop_background" ends them). reason becomes the run's reason (default user_cancel; the first cancel of a run names it). Tool subprocesses are not signalled here; that is the surface's to do. Only records the request, so a signal handler may call it. Outside a run it does nothing and returns false.
run_cancelled
True when the current run was cancelled ("cancel_run"); false outside a run. A question put to somebody (the hall's permission channel) stops waiting when it turns true.
event
$app->event('tool.call', call => 'c1', name => 'bash', arguments => { ... });
One event of the application, handed to every consumer: the session journal of the run in progress for the types it records (with the run's run id), the on_event of that run, and "on_event".
record
$app->record($session, 'history.cleared');
Appends one event outside a run to the session journal. A write that fails goes to "on_journal_error" and returns false.
raider
Returns the underlying Langertha::Raider instance (lazily built).
loaded_skill_names
my @names = $app->loaded_skill_names; # ('pdf', 'superpowers:brainstorming')
The names of the skills the mission lists and the skill tool loads ("listed" in Langertha::Raider::Context::Skills), in precedence order. For the banner and status display.
session_store
The Langertha::Raider::SessionStore of the project in "root" (ADR 0003, ADR 0015), built on first use.
create_session
my $session = $app->create_session;
A new session in "session_store", open for writing and locked ("create" in Langertha::Raider::SessionStore).
open_session
my $session = $app->open_session($id);
Opens the session $id of "session_store" for writing; croaks ... is in use while another raider holds it ("open" in Langertha::Raider::SessionStore).
replay_session
my $journal = $app->replay_session($session);
Replays the journal the Langertha::Raider::Session was opened with into "raider" (ADR 0015): history from the message events of the runs that got an answer, session_history from all events. Nothing is executed. Returns the Langertha::Raider::Session::Journal.
fork_session
my $fork = $app->fork_session($id);
# { id, path, forked_from, messages }
A new session in "session_store" whose session.created names the session $id in forked_from, and which takes over its working history -- what a resume would replay into history ("history_messages" in Langertha::Raider::Session::Journal) -- as message events outside any run. The original is only read (no lock needed) and never changed. Returns the new session's id and path, forked_from and how many messages it took over.
remove_session
my $path = $app->remove_session($id);
Deletes the session $id of "session_store", journal and lock file ("remove" in Langertha::Raider::SessionStore, which croaks session ID is in use while another raider has it open). Returns the journal's path.
reload_context
$app->reload_context;
$app->reload_mission;
Reads the Claude memory, the settings (with their env) and the skills again ("reload" in Langertha::Raider::Context) and drops the skill tool, so the next "reload_mission" mounts it again over the new catalogue -- or not at all when no skill is left. The agent tool is dropped the same way and comes back over the agent files as they are now. /reload does both. A pack decided at the start (the default packs of Claude mode) is not decided again.
reload_mission
Rebuilds the mission (e.g. after the instructions file has been edited) and swaps it into the underlying Langertha::Raider. An explicit "mission" is kept. When "perl_tools_grant" changed since the tool servers were mounted (/pack, /reload), the PerlTools server is mounted or unmounted first, so the engine offers the same tools the new mission describes from the next raid on; a raid resumed from a pending question re-gathers them too.
mission_source
Where the instructions item of "mission" comes from: the "source_label" of mission (-M on the command line) for a mission passed to the constructor; the "label" in Langertha::Raider::Instructions of the instructions file (.raider/instructions.md or .raider.md) when it customizes the default persona (never with "bare"); claude base in Claude mode ("claude_persona_off"); default otherwise.
source_label
my $label = $app->source_label('pack_names'); # 'pack_names', '--pack' in the CLI
How reports name a setting that was passed to the constructor: in "explain_config", "perl_tools_grant", "detection_state", "mission_source" and the pack sources. The keys are engine, model, api_key, engine_options, engine_options packs, pack_names, no_pack_names, perl, detect, no_detect, bare, mission, claude, cli_skill_sources, permission_mode and skip_permissions. A surface names its own way of setting them in "source_labels"; without, the label is the key.
source_labels
The labels of "source_label" by key; none here. The command line (Langertha::Raider::CLI) returns its flags.
explain_config
my $report = $app->explain_config;
Where each effective setting came from, constructor arguments included. The shape of "explain" in Langertha::Raider::Config, with source (and shadowed) naming an argument by its "source_label" (the command line names its flags: -e, -m, -k, -o, --pack, --perl, --claude, --openai/--skills), a layer of the config file by its "label" in Langertha::Raider::Config (.raider.yml, .raider.yml default:, .raider/config.yml openai:), a layer of the home file ~/.raider/config.yml (home, home default:, home openai:), an environment variable (env OPENAI_API_KEY) or default. A value merged from both files (no_detect, detect) names the home layer in merged_with. API key values are never included. Builds no engine. file is the config file in use and ignored_files the config files next to it that are not loaded ("ignored_files" in Langertha::Raider::Config); home_file is the home file, present only when it is loaded.
detection says whether pack detection runs (on, or off with what switched it off) and packs is the "activation_report" in Langertha::Raider::Packs::Collection: each pack with its source (flag, config, default, detected, manual), its origin (project, home, shipped, env) and, for detection rules, the clause that matched or failed. skipped_packs is "skipped_packs" in Langertha::Raider::Packs::Collection. perl_tools is "perl_tools_grant": whether the Perl tools are mounted, and why. session_embeddings is "session_embeddings": whether the session history is embedded, and why not (ADR 0028).
instructions is "mission_source" and bare is "bare". ignored_instructions_files are the instructions files that are present but not used ("ignored_files" in Langertha::Raider::Instructions): a legacy .raider.md next to .raider/instructions.md.
layout, memory, settings (only in the Claude layout), skills, shadowed_skills, skill_problems and plugins are "report" in Langertha::Raider::Context of "context": the layout mode and what decided it, the memory files with their imports, the Claude settings (their files, counts of the permission rules, the names -- never the values -- of the env keys, the enabled plugins, the hook events, the keys raider does not use), every skill with its root and whether it is listed, the skills shadowed by an earlier one of the same name, broken skill files, and the enabled plugins. claude is among values when set: by "claude", claude: or -o claude=.
permissions is "report" in Langertha::Raider::Permissions of "permissions": the mode and where it came from, mode names from files that were ignored, the valid rules per kind with their sources, the invalid rules and the additional directories. agents, shadowed_agents and agent_problems come from the same report ("report" in Langertha::Raider::Context::Agents): every agent a run could start (ADR 0020) with its root, its tools in raider names (* for all), the disallowed ones, the model it would get under this engine and "agent_models" (or why it inherits), its declared skills and those that do not resolve (missing_skills), the tool names and frontmatter keys raider does not use; the agents shadowed by an earlier one of the same name; and files in an agent root that are not agents.
tools lists the mounted tools, each with its name, its source (engine:N) and effects: what it can do, from a static built-in table (read, write, network, code, message; empty when it only steers the run), or undef when the table does not know the tool. Information only -- nothing is enforced by it.
project_tools is present when ~/.raider/config.yml has one (ADR 0011; "project_tools" in Langertha::Raider::Config): the file and label it was read from, selectors with whether each matches "root" and why, and tools, one entry per tool name that a selector names or an active pack requests (the tools: of its pack.yml; a project has no other way to request a tool yet): granted_by, the matching selectors naming it (empty: not granted); requested_by, the requesting packs (pack perl); and known, tool for a built-in or mounted tool, tool group for perl, undef for a name raider does not know (not an error). Information only -- the mounted tools do not follow it yet. A project_tools in the project file, inside a section, or given with -o is not read and is listed in ignored.
SEE ALSO
SUPPORT
Issues
Please report bugs and feature requests at https://github.com/Getty/langertha-raider/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 <torsten@raudssus.de> https://raudssus.de/
COPYRIGHT AND LICENSE
This software is copyright (c) 2026 by Torsten Raudssus.
This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself.