pitchfork
AGENTS.md713 starsChanged 13 days agoMITView on GitHub
This file documents repository conventions for coding agents. CLAUDE.md and CRUSH.md point to this guide. Pitchfork is a daemon supervisor CLI with a client-server architecture: Configs merge in order (later overrides earlier): 1. /etc/pitchfork/config.toml (system - namespace: global) 2. ~/.config/pitchfork/config.toml (user - namespace: global) 3. Project config files from filesystem root down to the current directory; within each directory: .config/pitchfork.toml < .config/pitchfork.local.toml < pitchfork.toml < pitchfork.local.toml Update rules: - Changing user settings → edit the #[derive(usage_rs::Config)] structs in src/settings.rs (sole…
Where files are headingNew AGENTS.md files have more rules about keeping secrets out of the code, and fewer about code style.
Of the AGENTS.md files we read, the 31,439 first seen in the last six months, against the older ones: the kind of rule that gained most share, and the kind that lost most. About files like this in general, not this one, and an estimate, since a kind is a pattern in the words.
In this repository4 other files it gives its agents.
- entire-searchSkill
- jouet-initSkill
- jouet-initSkill
- pitchforkSkill
The file
Show its rules and text
We split this AGENTS.md into the rules it gives an agent
18 rules. About 0 are common, 10 are distinctive, and 8 are very specific to this project.
≈0
Common · estimate
Many files like this have a rule of this kind.
≈10
Distinctive · estimate
This author's own choices. Worth a look.
8
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Distinctive: line 49
If supervisor isn't running, CLI auto-starts it in background
- Very specific: line 100
Async/Tokio: All I/O is async; use tokio::select!
- Very specific: line 101
Error handling: Use miette::Result for rich error messages
- Very specific: line 103
File locking: Always lock state file for concurrent access (xx::fslock)
- Very specific: line 104
Daemon commands: Run via the shell verbatim.
- Distinctive: line 105
Idiomatic Rust: Prefer standard Rust patterns and idioms
- Very specific: line 109
Use the lowest compatibility-significant specificity in Cargo.toml (for example, "1" for stable 1.x dependencies).
- Very specific: line 110
When the existing manifest requirement accepts a routine dependency update, change only Cargo.lock.
- Distinctive: line 111
Keep lockfile updates focused and avoid unrelated transitive dependency churn.
- Distinctive: line 116
SHOULD use the same format:
- Very specific: line 138
Start the description with a lowercase character, or with an acronym such as PGO or CLI
- Distinctive: line 139
Use imperative mood ("add feature" not "added feature")
- Distinctive: line 140
Keep it concise but descriptive
- Distinctive: line 162
Describe the final result: Before requesting review and again after feedback changes the implementation, compare the title and body with …
- Distinctive: line 166
Lead with the user-visible change: Keep the conventional commit format, but name the affected behavior and outcome in the title.
- Distinctive: line 177
Use measured results for performance claims and state how they were measured.
- Distinctive: line 199
When AI contributes GitHub content—including a pull request description, review, pull request comment, discussion post, or issue—append …
- Very specific: line 204
Use the exact model and version identifiers exposed by the runtime.
≈ “Common” is an estimate: at least 1 in 5 of the 40,246 AGENTS.md files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
Agent guide
This file documents repository conventions for coding agents. CLAUDE.md and CRUSH.md point to this guide.
Build Commands
# Build and restart supervisor
# (do not manually run cargo build, as it does not contain all necessary steps)
mise run build-dev
# MUST run this before committing
mise run ci-dev
# Run tests. It's already included in `ci-dev`
mise run test
# Run a single test
cargo nextest run test_name
# Lint (check)
cargo fmt --check
cargo clippy --all-targets --all-features -- -D warnings
# Lint (fix)
cargo fmt --all
cargo clippy --fix --allow-dirty --allow-staged --all-targets --all-features -- -D warnings
# Install dev build and start supervisor with debug logging
mise run install-dev
# Render CLI docs. It's already included in `ci-dev`
mise run renderArchitecture
Pitchfork is a daemon supervisor CLI with a client-server architecture:
Core Components
- CLI (
src/cli/) - User-facing commands that communicate with the supervisor via IPC - Supervisor (
src/supervisor/) - Background daemon that manages all child processes - IPC (
src/ipc/) - Unix domain socket communication with NUL-delimited JSON messages
How It Works
- CLI commands connect to the supervisor at
~/.local/state/pitchfork/sock/main.sock - If supervisor isn't running, CLI auto-starts it in background
- Supervisor spawns and monitors daemons, handles retries, cron scheduling, and autostop
- State persisted to
~/.local/state/pitchfork/state.tomlwith file locking for concurrency
Key Files
| File | Purpose |
src/supervisor/ | Supervisor module: lifecycle.rs (start/stop daemons), ipc_handlers.rs, watchers.rs (background watchers), retry.rs, autostop.rs, state.rs, hooks.rs, pty.rs |
src/ipc/ | Client/server IPC with JSON messages over Unix sockets |
src/pitchfork_toml.rs | Config file parsing and merging |
src/state_file.rs | Persistent state management |
src/daemon.rs | Daemon struct and state |
src/cli/start.rs | Main "start daemon" command logic |
Background Watchers (in src/supervisor/watchers.rs)
- Interval watcher: Refresh process state, autostop, retry failed daemons (interval from
general.intervalsetting, default 10s) - Cron watcher: Trigger scheduled tasks based on cron expressions (interval from
supervisor.cron_check_intervalsetting, default 10s) - File watcher: Restart daemons when their watched files change (
daemon_file_watch)
Config Hierarchy
Configs merge in order (later overrides earlier):
/etc/pitchfork/config.toml(system - namespace: global)~/.config/pitchfork/config.toml(user - namespace: global)- Project config files from filesystem root down to the current directory; within each directory:
.config/pitchfork.toml<.config/pitchfork.local.toml<pitchfork.toml<pitchfork.local.toml
Data Sources
| Source | Pipeline | Outputs |
src/settings.rs (#[derive(usage_rs::Config)]) | derive generates the settings registry and spec config block; mise run render renders it | docs/cli/configuration.md (settings reference), config block in pitchfork.usage.kdl |
| Rust usage-rs + schemars | mise run render: pitchfork usage → usage tool; pitchfork schema | docs/cli/*.md + docs/cli/commands.json (CLI reference); docs/public/schema.json (JSON Schema for editor autocomplete) |
Update rules:
- Changing user settings → edit the
#[derive(usage_rs::Config)]structs insrc/settings.rs(sole source of truth), then runmise run render - Changing CLI flags/args/help text (usage-rs) or config struct (schemars) → run
mise run render(runningmise run ci-devincludes itself, recommended) to regeneratedocs/cli/,docs/public/schema.json, andpitchfork.usage.kdl
These files are generated and should not be manually edited:
docs/cli/*.mddocs/cli/commands.jsondocs/public/schema.jsonpitchfork.usage.kdl
Partially generated:
docs/reference/settings.md— hand-authored prose; the full per-setting reference is the generateddocs/cli/configuration.mdit links to.
Code Patterns
- Async/Tokio: All I/O is async; use
tokio::select!for concurrent operations - Error handling: Use
miette::Resultfor rich error messages - Serialization: Heavy use of serde with TOML for config/state, JSON for IPC
- File locking: Always lock state file for concurrent access (
xx::fslock) - Daemon commands: Run via the shell verbatim; do NOT prepend
exec— it breaks compound commands (e.g.exec a && bsilently dropsb). Users can addexecthemselves in the run string for single commands - Idiomatic Rust: Prefer standard Rust patterns and idioms
Dependency Updates
- Use the lowest compatibility-significant specificity in
Cargo.toml(for example,"1"for stable 1.x dependencies). - When the existing manifest requirement accepts a routine dependency update, change only
Cargo.lock. - Keep lockfile updates focused and avoid unrelated transitive dependency churn.
Conventional Commits
PR titles MUST follow conventional commit format. Intermediate commit subjects SHOULD use the same format:
Format: <type>(<scope>): <description>
Types:
feat:- New features that affect the pitchfork CLI/applicationfix:- Bug fixes that affect the pitchfork CLI/application (not CI, docs, or infrastructure)refactor:- Code refactoringdocs:- Documentation changesstyle:- Code style/formatting (no logic changes)perf:- Performance improvementstest:- Testing changeschore:- Maintenance tasks, releases, dependency updates, CI/infrastructure changessecurity:- Security-related changesci:- CI and automation changesrevert:- Reverting a previous change
Scopes:
- For command-specific changes, use the command name:
start,stop,status,logs,run, etc. - For subsystem changes:
supervisor,ipc,config,state,daemon,cron,deps
Description Style:
- Start the description with a lowercase character, or with an acronym such as
PGOorCLI - Use imperative mood ("add feature" not "added feature")
- Keep it concise but descriptive
Examples:
fix(supervisor): handle graceful shutdown on SIGTERMfeat(start): add --restart-policy flagfeat(cron): support timezone-aware schedulingdocs: update configuration exampleschore: release 0.2.0chore(ci): fix linting in CI pipelinechore(deps): update dependencies
CI validates the pull request title and re-runs when it is edited. Intermediate commit subjects are not checked because pull requests are squash-merged. CI mechanically checks the allowed type, syntax, and lowercase- or acronym-leading description; imperative mood remains a review rule.
PR titles and descriptions are release-note inputs
PR titles and descriptions are source material for release notes, including those generated by Communique. Write them for a pitchfork user who has not read the diff or this conversation.
- Describe the final result. Before requesting review and again after feedback changes the implementation, compare the title and body with the complete current diff. Rewrite both when the scope changes. Remove abandoned approaches, stale requirements, and claims that the final code or validation no longer supports.
- Lead with the user-visible change. Keep the conventional commit format, but name the affected behavior and outcome in the title. Open the body with the problem or use case and what users can now do. Avoid titles such as "address feedback" or "fix CI" when the PR's actual purpose is a feature or behavior fix. For internal-only work, explain the concrete maintainer or contributor benefit without inventing a user-facing impact.
- Make the change concrete. For new configuration, commands, or APIs, include a small, valid example and explain its result. For a bug fix, describe the trigger and before/after behavior. For visible UI or output changes, include actual before/after screenshots or a short recording when they help reviewers assess the change; CLI input/output snippets are often clearer than terminal screenshots. Use measured results for performance claims and state how they were measured.
- Keep the essential facts in text. Caption screenshots and explain examples. A reader or release-note generator should understand the change without opening an image, following an external link, or reading the diff. Do not fabricate screenshots, output, measurements, or validation results.
- State adoption details when relevant. Include new flags or settings, defaults, supported platforms, experimental status, required dependency versions, and any compatibility changes or migration steps that affect using the feature. Distinguish current behavior from planned follow-ups; do not advertise unfinished work.
- Keep review details proportionate. Summarize meaningful validation and its limitations. Include implementation details only when they explain behavior or a tradeoff reviewers need to assess. Omit agent work logs, intermediate commit summaries, and exhaustive test-command lists. A small fix can be a short paragraph and a test result; screenshots and sections are not mandatory for every PR.
For a hypothetical fix, prefer fix(stop): wait for daemons to shut down gracefully
over fix: address review feedback. Its description should show the stop command and explain the resulting process lifecycle and timeout behavior.
These rules supplement the repository's existing commit, release, and disclosure
requirements.
GitHub Interactions
When AI contributes GitHub content—including a pull request description, review, pull request comment, discussion post, or issue—append this disclosure:
*AI-assisted — Tool: <tool>; model: <provider>/<model>; version: <version-or-unavailable>.*
Use the exact model and version identifiers exposed by the runtime. Never infer or guess them; use
unavailable when either value is not exposed.
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

