Workflow Rules for AI Assistants
This document explains the mandatory workflows that AI assistants must follow when working on BlueFly.io projects.
1. Issue-First Development
The Rule
NEVER start coding without a GitLab issue.
Every piece of work must be tracked in GitLab. This enables: - Progress tracking - Code review - Audit trails - Team coordination
The Process
User Request
↓
Create GitLab Issue (or find existing)
↓
Click "Create merge request" in GitLab UI
↓
GitLab creates branch + MR automatically
↓
Create worktree for branch
↓
Implement changes
↓
Push commits
↓
MR is reviewed and merged
↓
Cleanup worktree
Example
# 1. User says: "Add authentication to the API"
# 2. Create issue in GitLab
glab issue create --title "feat: Add API authentication" --description "..."
# 3. In GitLab UI: Click "Create merge request" on the issue
# 4. Fetch and create worktree
git fetch origin
git worktree add ../worktrees/123-add-api-auth 123-add-api-auth
# 5. Work in worktree
cd ../worktrees/123-add-api-auth
# ... make changes ...
git add . && git commit -m "feat: implement API authentication"
git push
# 6. After MR merges, cleanup
git worktree remove ../worktrees/123-add-api-auth
2. Worktree Workflow
The Rule
NEVER switch branches in main project directories.
Main directories (llm-platform, agent-buildkit, etc.) must ALWAYS stay on development branch.
Why?
- DDEV and Docker environments expect consistent state
- Multiple features can be developed simultaneously
- No risk of uncommitted changes being lost
- IDE indexes remain stable
Main Project Directories
These directories stay on development:
/Users/flux423/Sites/LLM/llm-platform
/Users/flux423/Sites/LLM/agent-buildkit
/Users/flux423/Sites/LLM/gitlab_components
/Users/flux423/Sites/LLM/technical-guide
/Users/flux423/Sites/LLM/all_drupal_custom/modules/*
/Users/flux423/Sites/LLM/all_drupal_custom/recipes/*
/Users/flux423/Sites/LLM/all_drupal_custom/themes/*
/Users/flux423/Sites/LLM/common_npm/*
/Users/flux423/Sites/LLM/models/*
Worktree Locations
Feature work goes to worktrees:
/Users/flux423/Sites/LLM/worktrees/<project>/<branch>/
Commands
# Setup worktree
git fetch origin
git worktree add ../worktrees/<branch> <branch>
# List worktrees
git worktree list
# Remove worktree
git worktree remove ../worktrees/<branch>
# Prune stale references
git worktree prune
3. Source vs Deployment Directories
The Rule
NEVER edit Composer-managed paths. Edit source directories instead.
The Mapping
| Edit Here (Source) | Syncs To (Deployment) |
|---|---|
all_drupal_custom/modules/ |
llm-platform/web/modules/custom/ |
all_drupal_custom/themes/ |
llm-platform/web/themes/custom/ |
all_drupal_custom/recipes/ |
llm-platform/web/recipes/ |
The Sync Process
# 1. Edit files in source directory
vim all_drupal_custom/modules/my_module/src/Controller/MyController.php
# 2. Sync to deployment
buildkit drupal sync
# 3. Test in deployment
ddev drush cr
# ... test functionality ...
# 4. Commit in source directory
cd all_drupal_custom/modules/my_module
git add .
git commit -m "feat: add MyController"
git push
Detection Pattern
If you see any path containing:
- llm-platform/web/modules/ → Redirect to all_drupal_custom/modules/
- llm-platform/web/themes/ → Redirect to all_drupal_custom/themes/
- llm-platform/web/recipes/ → Redirect to all_drupal_custom/recipes/
4. TDD Workflow (RED-GREEN-REFACTOR)
The Rule
NEVER write implementation before tests.
The Cycle
RED: Write failing test
↓
GREEN: Write minimal code to pass
↓
REFACTOR: Improve code (tests still pass)
↓
Repeat
Example
// 1. RED - Write failing test first
describe('AuthService', () => {
it('should authenticate with valid credentials', async () => {
const result = await authService.login('user@test.com', 'password')
expect(result.success).toBe(true)
})
})
// Run: npm test → FAILS (AuthService doesn't exist)
// 2. GREEN - Write minimal implementation
class AuthService {
async login(email: string, password: string) {
return { success: true }
}
}
// Run: npm test → PASSES
// 3. REFACTOR - Improve while tests pass
class AuthService {
constructor(private userRepo: UserRepository) {}
async login(email: string, password: string) {
const user = await this.userRepo.findByEmail(email)
if (!user || !await bcrypt.compare(password, user.hash)) {
throw new AuthError('Invalid credentials')
}
return { success: true, token: this.generateToken(user) }
}
}
// Run: npm test → Still PASSES
Coverage Requirements
- Minimum: 80% code coverage
- Run:
npm test -- --coverageorphpunit --coverage-html coverage
5. Agent Spawning Workflow
The Rule
Spawn agents for tasks > 500 tokens or > 3 files.
Decision Process
Is task > 500 tokens?
├── YES → Spawn agent
└── NO ↓
Does task affect > 3 files?
├── YES → Spawn agent
└── NO ↓
Is task repetitive across files?
├── YES → Spawn agent
└── NO → Work directly
How to Spawn
# 1. Check for existing agents
buildkit agents search --tag <keyword>
# 2. If found, use existing agent
buildkit agents run <agent-id> --input '{"task": "..."}'
# 3. If not found, spawn new worker
buildkit swarm spawn --type worker
# 4. For batch operations
buildkit swarm create-tasks --files "src/**/*.ts" --output tasks.json
buildkit swarm spawn --tasks tasks.json --runtime local
Examples of When to Use Agents
- ✅ Refactoring 10 files to use new API
- ✅ Generating tests for all controllers
- ✅ Updating documentation across modules
- ✅ Fixing PHPCS violations in 50 files
- ❌ Fixing a single bug in one file
- ❌ Adding a small feature to one module
- ❌ Answering a question about the codebase
6. GitLab Issue Creation Rules
The Rule
NEVER create issues without explicit user approval.
There are 700+ open issues due to mass creation. We must stop creating new issues without need.
Before Creating ANY Issue
- Search first - Check if issue already exists
- Ask user - "Should I create an issue for X?"
- One at a time - Max 3 issues per request
- Single project - One issue belongs to ONE project
What NOT to Create
- ❌ Same issue in multiple projects
- ❌ "Nice to have" feature ideas
- ❌ Roadmap/planning issues (use Wiki)
- ❌ Issues during exploratory work
- ❌ Compliance issues across all modules (consolidate)
What TO Do Instead
- ✅ Update existing issues
- ✅ Close completed issues
- ✅ Use Wiki for planning documents
- ✅ Focus on closing existing backlog
7. Issue Closing Verification (MANDATORY)
The Rule
NEVER close an issue without verifying completion.
⚠️ DISASTER HISTORY: On 2025-11-30, 16 important issues were wrongly closed because an AI assumed "milestone closing = issues done". See Critical Warnings.
Before Closing ANY Issue
# 1. Get issue details with comments
glab api projects/{project-id}/issues/{issue-iid}/notes
# 2. Look for completion markers:
# - "✅ COMPLETED" or "✅ Done"
# - "Merged in MR !{number}"
# - "Closing as completed"
# 3. If no clear completion marker, ASK:
echo "Issue #{issue-iid} has no completion comment - should I close it?"
Completion Evidence Required
| Evidence Type | Example | Valid? |
|---|---|---|
| Explicit completion comment | "✅ COMPLETED in MR !45" | ✅ Yes |
| Merged MR linked | MR !45 (merged) | ✅ Yes |
| Assigned to milestone | Milestone v0.2.7 | ❌ NO - not evidence |
| Has WIP comment | "Working on this" | ❌ NO - still in progress |
| No comments at all | (empty) | ❌ NO - not started |
Bulk Close Operations
NEVER do bulk closes without individual verification:
# WRONG - CATASTROPHIC
for issue in $(glab issue list); do
glab issue close $issue
done
# RIGHT - Verify each
for issue in $(glab issue list); do
echo "\n=== Issue $issue ==="
glab api projects/{id}/issues/{issue}/notes | jq '.[] | .body'
read -p "Has completion marker? Close? (y/n): " confirm
[ "$confirm" = "y" ] && glab issue close $issue
done
Milestone Does NOT Equal Completion
Critical misconception that caused the disaster:
- Milestone v0.2.7 was being closed as failed (version burned on npm)
- AI assumed "milestone closing = work complete"
- 16 issues were closed that were NOT done
- Lost tracking of important in-progress work
Milestone states:
| Milestone State | Issue Implication |
|---|---|
| Open | Issues are planned for this release |
| Closed (success) | Issues SHOULD be done (verify anyway) |
| Closed (failed) | Issues need to move to next milestone |
8. npm Publishing Workflow (MANDATORY)
The Rule
npm versions are PERMANENT. Once published, that version number is gone FOREVER.
⚠️ DISASTER HISTORY: On 2025-11-30, versions 0.2.6 and 0.2.7 were burned (published broken, can never be reused). See Critical Warnings.
The Safe Publishing Process
# 1. Verify everything passes
npm test
npm run build
npm run validate:schema # If applicable
# 2. Publish to RC tag FIRST (still burns version, but marked as pre-release)
npm publish --tag rc
# 3. Test the RC in a SEPARATE project
mkdir /tmp/test-package && cd /tmp/test-package
npm init -y
npm install @bluefly/package@rc
# ... run tests ...
# 4. ASK USER before promoting
echo "RC version tested successfully. Promote to latest? This is IRREVERSIBLE."
# 5. Only after explicit approval, promote
npm dist-tag add @bluefly/package@{version} latest
If You Burn a Version
# The version is GONE. Skip to next number.
# If you burned 0.2.6, next release must be 0.2.7 or higher.
# Set last good version as latest
npm dist-tag add @bluefly/package@{last-good} latest
# Deprecate burned version
npm deprecate @bluefly/package@{burned} "Broken release - use {last-good}"
# Update ALL references to skip burned version
# package.json, schemas, docs, manifests, etc.
Summary Checklist
Before starting work:
- [ ] GitLab issue exists (or user approved creation)
- [ ] Working in correct directory (source, not deployment)
- [ ] Using worktree (not switching branches in main dir)
- [ ] Tests written first (TDD)
- [ ] Checked if agents should be used (buildkit golden optimize)
During work:
- [ ] Commits reference issue number
- [ ] Tests pass before push
- [ ] PHPCS/ESLint clean
After work:
- [ ] MR created and linked to issue
- [ ] Worktree cleaned up
- [ ] Main directory back on development