How Workflow Commands Are Managed in the AI Job Search Framework
Workflow commands in the AI Job Search framework are defined declaratively in Markdown specification files under .claude/commands/, rather than implemented as hard-coded logic, enabling runtime interpretation without recompilation.
The MadsLorentzen/ai-job-search repository employs a unique declarative command architecture where every user-facing workflow—such as /apply, /scrape, and /rank—is fully specified in a human-readable Markdown file. This design separates workflow orchestration from implementation, making the system auditable, extensible, and portable across multiple agent runtimes.
Command Definitions in .claude/commands/
Each workflow command resides as a standalone Markdown file in the hidden directory .claude/commands/. These files serve as the single source of truth for command behavior.
A command specification includes:
- Input contract — what arguments the command accepts
- Step-by-step workflow — which skill modules are invoked and how data flows between steps
- Security rules — Bash actions permitted via the project-wide allowlist
- Output contract — generated files (CV, cover letter, PDF) and their delivery mechanism
The top-level AGENTS.md file directs every agent runtime to these canonical specifications, implementing a thin-pointer design that keeps runtimes synchronized without code duplication.
Skill Module Invocation
Actual work is performed by skill modules located in .claude/skills/ and .agents/skills/. Command files reference these skills by name, ensuring workflow definitions remain agnostic to concrete implementations.
This decoupling allows skills to evolve independently—for example, the job-application-assistant skill could be rewritten without modifying the /apply command specification that invokes it.
Security Enforcement Through Allowlists
The framework enforces strict security boundaries via .claude/settings.json, which enumerates exactly which Bash commands a workflow may execute. Examples include lualatex for PDF compilation.
The CI job security-guards validates that no command file attempts to widen this allowlist. This guarantees that workflows cannot execute unsafe shell code, even if a command specification is compromised.
Runtime Execution Flow
When a user runs a command via CLI:
- The CLI reads the corresponding Markdown spec (e.g.,
.claude/commands/apply.md) - Arguments are interpolated into the specification
- Steps are dynamically executed, invoking referenced skills
- Output files are generated and presented to the user
This architecture means entire workflows can be updated by editing Markdown—no recompilation or redeployment required.
Example: Running the /apply Command
# Execute the full application workflow for a job posting
ai-job-search /apply https://jobindex.dk/job/12345
Example: Command Specification Structure
<!-- .claude/commands/apply.md (excerpt) -->
# /apply command
## Arguments
- $ARGUMENTS: job posting URL or raw text
## Workflow
1. Store the posting verbatim (untrusted data rule)
2. Invoke the `job-application-assistant` skill for fit evaluation
3. Generate CV & cover letter using the active LaTeX template
4. Run the verification checklist from `CLAUDE.md`
5. Compile PDFs with `<CV_COMPILE>` / `<COVER_COMPILE>` (allowed by settings.json)
6. Present final output to the user
Simplified Execution Glue
def run_apply(url: str):
posting = fetch_posting(url) # step 1
evaluation = invoke_skill('job-application-assistant', posting) # step 2
cv_pdf, cover_pdf = render_documents(evaluation) # steps 3-5
verify_and_present(cv_pdf, cover_pdf) # step 6
Core Command Files and Their Roles
| File | Purpose |
|---|---|
.claude/commands/apply.md |
Defines the /apply workflow for drafting and submitting applications |
.claude/commands/rank.md |
Orchestrates /rank for scoring scraped postings before handoff to /apply |
.claude/commands/setup.md |
Initializes candidate profile data for subsequent commands |
AGENTS.md |
Thin-pointer file directing all agent runtimes to canonical specifications |
README.md |
High-level overview of available workflow commands |
SECURITY.md |
Documents permission model and safety guarantees |
.claude/settings.json |
Machine-readable allowlist of permitted Bash commands |
Summary
- Workflow commands are Markdown-first — behavior is declared in
.claude/commands/files, not encoded in source code - Single source of truth —
AGENTS.mdand command specs keep multiple runtimes synchronized - Security by design —
.claude/settings.jsonallowlist plussecurity-guardsCI prevents unsafe execution - Zero-downtime updates — edit command specs without recompilation or redeployment
- Clean separation — workflow orchestration (commands) is decoupled from implementation (skills)
Frequently Asked Questions
How does the AI Job Search framework prevent malicious code execution in workflow commands?
The framework implements defense in depth: .claude/settings.json maintains an explicit allowlist of permitted Bash commands, the security-guards CI job validates that command files never expand this list, and SECURITY.md documents the permission model. Commands can only invoke shell tools that have been pre-approved.
Can I add a new workflow command without modifying Python code?
Yes. Create a new Markdown file in .claude/commands/ following the established specification format, define your inputs/outputs, reference existing or new skills, and ensure any required Bash commands are added to .claude/settings.json with proper security review. The CLI will automatically recognize and execute the new command.
What happens if a skill implementation changes—do command files break?
No. Command files reference skills by stable names, not by implementation details. As long as the skill maintains its interface contract, the underlying implementation can be refactored, upgraded, or replaced without touching command specifications.
Where is the authoritative list of available workflow commands?
The AGENTS.md file at repository root serves as the canonical index, pointing all agent runtimes to the command specifications in .claude/commands/. For human-readable documentation, see README.md.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →