We track work in Beads instead of Markdown. Run `bd quickstart` to see how.
ALWAYS ask clarifying questions when requirements are ambiguous or unclear.
When you receive a request that is:
- Ambiguous or has multiple interpretations
- Missing key details needed for implementation
- Unclear about expected behavior or scope
- Could be understood in different ways
YOU MUST:
- ✅ Ask ONE clarifying question at a time
- ✅ Wait for the answer before proceeding
- ✅ Continue asking questions until you have complete understanding
- ✅ Never make assumptions when you can ask
❓ Ambiguous request: "Add a loading state"
- Ask: "Should this be a full-screen loading indicator, an inline spinner, or a skeleton view?"
❓ Missing details: "Add animation"
- Ask: "What should be animated? Should this use a spring animation, easing curve, or custom timing?"
❓ Unclear scope: "Improve performance"
- Ask: "Which area needs optimization? View updates, data fetching, or list scrolling performance?"
❓ Multiple interpretations: "Handle errors"
- Ask: "Should errors be shown in an alert, inline message, or banner? Should they auto-dismiss?"
❌ Don't make assumptions and implement something that might be wrong ❌ Don't ask multiple questions in one message (ask one, wait for answer, then ask next) ❌ Don't proceed with unclear requirements hoping you guessed correctly ❌ Don't over-explain options in the question (keep questions concise)
"I want to make sure I understand correctly: [restate what you think they mean].
Is that correct, or did you mean [alternative interpretation]?"
Remember: It's better to ask and get it right than to implement the wrong thing quickly.
This project uses a dynamic skill loading system where the LLM should:
- Analyze the task to determine which skills are required
- Load only the necessary skills by reading their SKILL.md files
- Apply the skill knowledge during task execution
- Unload skills from working memory when no longer needed
| Skill | Load When | Description |
|---|---|---|
| beads_workflow | Managing tasks, tracking work, creating issues | Complete bd workflow for task tracking with dependency management |
| commit_workflow | Committing code, managing git history | Incremental commit strategy - commit after each feature completion |
| communication_protocol | ALWAYS (every interaction) | Ask clarifying questions when requirements are ambiguous |
| temporary_files | ALWAYS (every interaction) | All AI-generated temporary files go to tmp/ directory |
| oneshot | User explicitly requests "oneshot [task]" | Complete uninterrupted execution of entire task/epic with final summary only |
| pre_commit_checks | Before committing code | Automated format/build/test checks before every commit |
| swift | Writing/refactoring Swift/SwiftUI code | Modern Swift and SwiftUI best practices, testing, documentation |
Before starting any task:
-
Identify required skills based on task type:
- User says "oneshot [task]" → Load
oneshotskill (takes over execution) - Code changes → Load
swiftskill - Task tracking → Load
beads_workflowskill - Git operations → Load
commit_workflowskill - Ambiguous requirements →
communication_protocol(always active) - Temporary files →
temporary_files(always active) - Pre-commit → Load
pre_commit_checksskill
- User says "oneshot [task]" → Load
-
Load skills by reading the appropriate SKILL.md file:
Read: skills/<skill_name>/SKILL.mdIMPORTANT: When loading a skill, the LLM MUST announce it in the chat response:
🔧 Loading skill: <skill_name> -
Apply skill knowledge during task execution
-
Unload skills when done:
- Keep only relevant skills in working memory
- Unload skills that are no longer needed for current task
- Communication protocol and temporary_files are ALWAYS active (never unload)
IMPORTANT: When unloading a skill, the LLM MUST announce it in the chat response:
✓ Unloading skill: <skill_name>
Task received
↓
Analyze task type
↓
┌──────────────────────────────────────┐
│ Did user say "oneshot [task]"? │ → YES → Load: oneshot (takes over execution)
└──────────────────────────────────────┘
↓ NO
┌──────────────────────────────┐
│ Is this a code writing task? │ → YES → Load: swift
└──────────────────────────────┘
↓ ALSO CHECK
┌──────────────────────────────┐
│ Is this task tracking? │ → YES → Load: beads_workflow
└──────────────────────────────┘
↓ ALSO CHECK
┌──────────────────────────────┐
│ Is this a git commit? │ → YES → Load: commit_workflow, pre_commit_checks
└──────────────────────────────┘
↓ ALSO CHECK
┌──────────────────────────────┐
│ Are requirements unclear? │ → YES → Use: communication_protocol (already loaded)
└──────────────────────────────┘
↓
Execute task with loaded skills
↓
Task complete
↓
Unload skills no longer needed
Common task scenarios and their skill requirements:
| Task Scenario | Skills to Load |
|---|---|
| Oneshot execution | oneshot (then loads others as needed: swift, commit_workflow, etc.) |
| Implement new feature | swift, beads_workflow |
| Fix bug | swift, beads_workflow |
| Commit code | commit_workflow, pre_commit_checks |
| Create/update issue | beads_workflow |
| Clarify requirements | communication_protocol (always active) |
| Write tests | swift |
| Refactor code | swift, commit_workflow |
Scenario: User asks to "implement a custom SwiftUI button component"
LLM Response:
I'll implement a custom SwiftUI button component for you.
🔧 Loading skill: beads_workflow
🔧 Loading skill: swift
First, let me create an issue to track this work...
[Creates issue using beads_workflow]
Now I'll implement the button component following Swift and SwiftUI best practices...
[Implements code using swift skill]
Writing comprehensive tests...
[Writes tests using swift skill]
Updating issue progress...
[Updates issue using beads_workflow]
The implementation is complete. Now let me commit the changes.
✓ Unloading skill: swift
🔧 Loading skill: commit_workflow
🔧 Loading skill: pre_commit_checks
Running pre-commit checks...
[Executes build, test]
Committing changes...
[Creates commit using commit_workflow]
✓ Unloading skill: commit_workflow
✓ Unloading skill: pre_commit_checks
Closing the issue...
[Closes issue using beads_workflow]
✓ Unloading skill: beads_workflow
✅ Custom button component implemented, tested, and committed!
To load a skill:
Read the SKILL.md file for that skill to understand the complete workflow and patterns.
To reference quick usage:
Read the USAGE.md file for quick reference on when to use the skill.
To unload a skill:
Remove skill knowledge from working memory when no longer relevant to current task.
- Communication protocol and temporary_files are ALWAYS active - never need loading/unloading (no announcement needed)
- Load skills lazily - only when needed
- Unload proactively - free up working memory
- Combine skills when tasks require multiple areas of expertise
- Reload if needed - Can reload a skill if task requirements change
- Always announce - Use
🔧 Loading skill: <name>and✓ Unloading skill: <name>in chat responses - Transparency - Skill loading/unloading announcements help users understand the LLM's decision-making process
Before every commit, these checks MUST pass:
- Build success -
swift buildor Xcode build (no compilation errors) - Test success -
swift testor Xcode tests (all tests pass) - SwiftFormat (optional) -
swiftformat .(if configured) - SwiftLint (optional) -
swiftlint(if configured)
Automation Level: Recommended but Optional
- Recommended: Install pre-commit hooks to automate checks (see
skills/pre_commit_checks/SKILL.md) - Acceptable: Run checks manually before each commit
- Not Acceptable: Commit without running checks
Installing Pre-Commit Hooks (Optional but Recommended):
# Create .git/hooks/pre-commit
cat > .git/hooks/pre-commit << 'EOF'
#!/bin/bash
swift build || exit 1
swift test || exit 1
# Optional: Add swiftformat/swiftlint if configured
EOF
chmod +x .git/hooks/pre-commitSee skills/pre_commit_checks/SKILL.md for complete setup guide.
IMPORTANT: This project uses bd (beads) for ALL issue tracking. Do NOT use markdown TODOs, task lists, or other tracking methods.
- Dependency-aware: Track blockers and relationships between issues
- Git-friendly: Auto-syncs to JSONL for version control
- Agent-optimized: JSON output, ready work detection, discovered-from links
- Prevents duplicate tracking systems and confusion
Check for ready work:
bd ready --jsonCreate new issues:
bd create "Issue title" -t bug|feature|task -p 0-4 --json
bd create "Issue title" -p 1 --deps discovered-from:bd-123 --jsonClaim and update:
bd update bd-42 --status in_progress --json
bd update bd-42 --priority 1 --jsonComplete work:
bd close bd-42 --reason "Completed" --jsonbug- Something brokenfeature- New functionalitytask- Work item (tests, docs, refactoring)epic- Large feature with subtaskschore- Maintenance (dependencies, tooling)
0- Critical (crashes, data loss, broken builds)1- High (major features, important bugs)2- Medium (default, nice-to-have)3- Low (polish, optimization)4- Backlog (future ideas)
- Check ready work:
bd readyshows unblocked issues - Claim your task:
bd update <id> --status in_progress - Work on it: Implement, test, document
- Discover new work? Create linked issue:
bd create "Found bug" -p 1 --deps discovered-from:<parent-id>
- Complete:
bd close <id> --reason "Done" - Commit together: Always commit the
.beads/issues.jsonlfile together with the code changes so issue state stays in sync with code state
bd automatically syncs with git:
- Exports to
.beads/issues.jsonlafter changes (5s debounce) - Imports from JSONL when newer (e.g., after
git pull) - No manual export/import needed!
If using Claude or MCP-compatible clients, install the beads MCP server:
pip install beads-mcpAdd to MCP config (e.g., ~/.config/claude/config.json):
{
"beads": {
"command": "beads-mcp",
"args": []
}
}Then use mcp__beads__* functions instead of CLI commands.
DEFAULT: ALL AI-generated documents go to tmp/ unless user explicitly requests otherwise.
AI assistants create documents during development. By default, ALL of these go to tmp/:
Store in tmp/ directory by default:
- Session summaries, completion reports →
tmp/summaries/ - Investigation notes, analysis →
tmp/analysis/ - Implementation plans, design docs →
tmp/plans/ - Debug output, test results →
tmp/debug/ - Scratch scripts and utilities →
tmp/scratch/
Characteristics:
- Created during development work
- Useful for current session/task
- Must be gitignored
- Can be deleted when no longer needed
Decision Tree:
Did user explicitly request a different location?
├─ NO → tmp/ (DEFAULT for ALL AI-generated content)
└─ YES → Use the location user requested (root, history/, etc.)
- ✅ Use bd for ALL task tracking
- ✅ Always use
--jsonflag for programmatic use - ✅ Link discovered work with
discovered-fromdependencies - ✅ Check
bd readybefore asking "what should I work on?" - ✅ Store AI-generated docs in
tmp/by default (unless explicitly requested otherwise) - ❌ Do NOT create markdown TODO lists
- ❌ Do NOT use external issue trackers
- ❌ Do NOT duplicate tracking systems
- ❌ Do NOT clutter repo root with temporary documents
For complete details, see skills/beads_workflow/SKILL.md.
These apply to ALL work on this project:
When requirements are ambiguous or unclear, ASK CLARIFYING QUESTIONS before proceeding. One question at a time. Wait for answer. Never assume.
Use Swift's type system to prevent bugs. Prefer optionals over force unwrapping. Use enums for state. Leverage protocols for abstraction.
Write declarative views. Avoid imperative code. Let SwiftUI manage view updates. Use proper state management.
No retain cycles. Use [weak self] or [unowned self] in closures. Be aware of ARC. Prefer value types (struct) over reference types (class) when possible.
Write comprehensive tests for all implementations. Test-driven development (TDD) is encouraged but not mandatory. All features, edge cases, and error conditions must have test coverage before committing.
Minimize view body computation. Use lazy loading. Cancel tasks on disappear. Profile with Instruments when needed. But clarity comes first.
COMMIT AFTER EVERY LOGICAL UNIT OF WORK. This is non-negotiable. Do not accumulate changes. Commit when you:
- Complete a feature or fix
- Finish refactoring a module
- Add tests that pass
- Update documentation
- Make any working, tested change
Use descriptive commit messages following the project's conventional commit style. See "Workflow" sections below for commit procedures.
All tasks, bugs, and features tracked in bd (beads). Always use bd ready --json to check for work. Link discovered issues with discovered-from. Never use markdown TODOs.
DEFAULT: ALL AI-generated summaries, analyses, plans, and temporary documentation MUST go into tmp/ directory by default. Never clutter project root. Only place files elsewhere when user explicitly requests it. See skills/temporary_files/SKILL.md for complete policy.
This project maintains production-ready standards:
- Zero tolerance for crashes
- Zero tolerance for memory leaks (retain cycles)
- Zero tolerance for untested code
- Zero tolerance for missing documentation on public APIs
- Zero tolerance for breaking changes without consideration
Before following any workflow below, internalize this rule:
✅ COMMIT FREQUENTLY - After every working, tested change:
- Completed a feature → Commit
- Fixed a bug → Commit
- Added tests that pass → Commit
- Refactored a module → Commit
- Updated documentation → Commit
DON'T accumulate changes. Small, focused commits are better than large ones. See Golden Rule #6.
- Check bd for issue -
bd ready --jsonor create new issue if needed - Claim the issue -
bd update bd-N --status in_progress --json - Understand requirements - Ask clarifying questions if needed
- Write tests first (optional but recommended) - Test desired behavior
- Implement feature - Follow Swift/SwiftUI best practices
- Document - Add doc comments for public APIs (do this BEFORE committing)
- Verify - Build succeeds, all tests pass
- ✅ COMMIT - Implementation + tests + docs together (see Golden Rule #6)
- Update CHANGELOG.md (if applicable) - Document what was added
- ✅ COMMIT - Commit changelog update
- Close issue -
bd close bd-N --reason "Implemented" --json
Remember: Commit after EACH working step. Implementation + tests + docs = ONE commit. Changelog is separate.
- Check bd for issue - or create:
bd create "Bug: ..." -t bug -p 1 --json - Claim the issue -
bd update bd-N --status in_progress --json - Write failing test that reproduces the bug
- Fix the bug with minimal code change
- Document - Add/update doc comments if needed
- Verify all tests pass (including new test)
- ✅ COMMIT - Fix + test + docs together with clear description
- Update CHANGELOG.md (if user-visible)
- ✅ COMMIT - Commit changelog update
- Close issue -
bd close bd-N --reason "Fixed" --json
Remember: Commit after EACH working step. Fix + test + docs = ONE commit. Changelog is separate.
skills/
├── swift/ # ⭐ Swift and SwiftUI best practices
│ ├── USAGE.md # When to use (autodiscovery)
│ └── SKILL.md # Complete documentation
├── communication_protocol/ # ⭐ Ask clarifying questions when unclear
│ ├── USAGE.md # When to use (autodiscovery)
│ └── SKILL.md # Complete documentation
├── pre_commit_checks/ # Automated quality checks
│ ├── USAGE.md # When to use (autodiscovery)
│ └── SKILL.md # Complete documentation
├── beads_workflow/ # ⭐ Task tracking with bd (beads)
│ ├── USAGE.md # When to use (autodiscovery)
│ └── SKILL.md # Complete documentation
├── commit_workflow/ # ⭐ Incremental commit strategy
│ ├── USAGE.md # When to use (autodiscovery)
│ └── SKILL.md # Complete documentation
├── temporary_files/ # ⭐ Temporary file management
│ ├── USAGE.md # When to use (autodiscovery)
│ └── SKILL.md # Complete documentation
└── oneshot/ # ⭐ Uninterrupted execution mode
├── USAGE.md # When to use (autodiscovery)
└── SKILL.md # Complete documentation
.beads/
└── issues.jsonl # Beads issue tracking database (git-versioned)
tmp/ # Gitignored temporary files (AI-generated)
├── summaries/ # Session summaries, completion reports
├── analysis/ # Investigation notes, code analysis
├── plans/ # Implementation plans, design docs
├── debug/ # Debug output, test results
└── scratch/ # Any other temporary work
Sources/ # Swift source code (if SPM project)
Tests/ # Test files
Root:
├── CHANGELOG.md # Version history and changes
├── CONTRIBUTING.md # Contribution guidelines
├── AGENTS.md (this file) # AI agent instructions
├── Package.swift # Swift Package Manager manifest (if SPM)
└── *.xcodeproj/ # Xcode project (if applicable)
CRITICAL: Temporary files MUST go into tmp/ directory, NOT project root.
DEFAULT BEHAVIOR: ALL AI-generated documents go to tmp/ unless user explicitly requests otherwise.
See skills/temporary_files/SKILL.md for complete policy and detailed guidelines.
Organized subdirectories:
tmp/summaries/- Session summaries, completion reportstmp/analysis/- Investigation notes, code analysistmp/plans/- Implementation plans, design docstmp/debug/- Debug output, test resultstmp/scratch/- Any other temporary work
| Directory | Purpose | Gitignored? | Examples |
|---|---|---|---|
tmp/summaries/ |
Session summaries | Required | session_2025-11-20.md, epic_summary.md |
tmp/analysis/ |
Investigation work | Required | performance_analysis.md |
tmp/plans/ |
Design documents | Required | feature_design.md |
tmp/debug/ |
Debug output | Required | test_results.txt, build_log.txt |
tmp/scratch/ |
Other temporary | Required | quick_notes.md |
| Root | Permanent project docs | No | README.md, CHANGELOG.md, CONTRIBUTING.md |
DEFAULT BEHAVIOR: ALL AI-generated documents go to tmp/ unless user explicitly requests otherwise.
-
✅ All temporary files MUST go in
tmp/BY DEFAULT- Session summaries and completion reports →
tmp/summaries/ - Investigation notes and analysis →
tmp/analysis/ - Implementation plans and design docs →
tmp/plans/ - Debug output and test results →
tmp/debug/ - Scratch scripts and utilities →
tmp/scratch/ - This includes: planning docs, summaries, analyses, debug output, temporary scripts
- Exception: ONLY when user explicitly requests a different location
- Session summaries and completion reports →
-
✅
tmp/directory MUST be gitignored- Verify
.gitignoreincludes/tmp/ - Create directory if it doesn't exist
- Never commit temporary files
- Verify
-
⚠️ Project root is ONLY for user-requested permanent documentation- User must explicitly say: "create this in the root" OR "this should be committed"
- Examples: "Add MIGRATION_GUIDE.md to the root", "Create permanent design doc"
- Do NOT assume files belong in root just because they seem important
❌ WRONG - Writing to project root:
ANALYSIS.md # ❌ Should be tmp/analysis/analysis.md
INVESTIGATION_NOTES.md # ❌ Should be tmp/analysis/investigation_notes.md
SESSION_SUMMARY.md # ❌ Should be tmp/summaries/session_summary.md
✅ CORRECT - Writing to tmp/:
tmp/analysis/performance_analysis.md # ✅ Temporary analysis
tmp/analysis/investigation_notes.md # ✅ Temporary notes
tmp/summaries/session_summary.md # ✅ Session summary
tmp/plans/feature_plan.md # ✅ Implementation plan
tmp/debug/test_results.txt # ✅ Debug output
✅ CORRECT - Permanent files (when explicitly requested):
ARCHITECTURE.md # ✅ Permanent reference (explicitly requested)
CHANGELOG.md # ✅ Project documentation
CONTRIBUTING.md # ✅ Project documentation
Only place files in project root when user explicitly says:
- "Create a permanent reference document in the root"
- "Add this to the project documentation"
- "This should be committed to the repo"
Otherwise, default to tmp/ for all generated content.
- ASK A CLARIFYING QUESTION ⭐ - Don't assume, just ask (one question at a time)
- Check bd for existing issues -
bd ready --json- See if work is already tracked - Have you committed recently? ⭐⭐⭐ - If you have working changes, commit them NOW
- Creating files? - Put generated docs/scripts in
tmp/unless explicitly requested otherwise - Load relevant skills - Get specialized guidance for Swift/SwiftUI development
- Look at existing code - See patterns in the codebase
- Follow the Golden Rules - Especially type safety, committing, and task tracking
- Crashes in production code
- Retain cycles and memory leaks
- Force unwrapping without justification
- Untested code
- Missing documentation on public APIs
- Generated files in project root (must use
tmp/unless explicitly requested otherwise) - Accumulating uncommitted changes (commit after every logical unit of work)
- Main thread violations (UI updates must be on main thread)
Quality over speed. Take time to do it right. Swift and SwiftUI reward good architecture.
Skills are context-aware. They provide specialized guidance for Swift development.
Thank you for maintaining the high quality standards of this project! 🎉