TASKS.md — scaffolder v0.9.0 workflow enforcement + bug fixes
TASKS.md — scaffolder v0.9.0 workflow enforcement + bug fixes
Section titled “TASKS.md — scaffolder v0.9.0 workflow enforcement + bug fixes”Rules for Code
Section titled “Rules for Code”- Always work on a feature branch, never directly on dev or main
- Read CLAUDE.md and STANDARDS.md before starting any work
- Read sessions/CURRENT.md for project state
- Complete each task fully before moving to the next
- Do not add features not listed here
- Follow Conventional Commits format on every commit
- Update sessions/CURRENT.md at the end of every session
- All merges require PRs
Branch strategy for this release
Section titled “Branch strategy for this release”Multiple feature branches, all merging to dev via PR:
fix/v0.9.0-bugs— Tasks 1-5 (bug fixes)feature/v0.9.0-ruleset— Tasks 6-8 (sc ruleset command)feature/v0.9.0-scale-workflow— Tasks 9-11 (scale-tier workflow)feature/v0.9.0-claude-review— Task 12 (enable Claude review)feature/v0.9.0-release— Task 13 (version bump, changelog, docs)
When ALL branches are merged to dev and tested:
- Code reports to operator that dev is ready
- Operator handles: dev → staging (PR) → test → staging → main (PR) → tag
Code never creates PRs to staging or main. Code never merges to staging or main. Code never tags releases. These are operator decisions.
Version target
Section titled “Version target”v0.9.0
Context
Section titled “Context”This release fixes critical bugs found in v0.8.1 testing, adds workflow enforcement via scale-tier-aware branch strategies, and introduces the sc ruleset command for switching between solo and team presets.
Pre-work
Section titled “Pre-work”Before starting Task 1:
- Create GitHub milestone: v0.9.0
- Create GitHub issues for each task (Tasks 1-13)
- Clean up test repos from earlier:
gh repo delete purlshq/create --yes 2>/dev/nullgh repo delete purlshq/test-tomorrow --yes 2>/dev/null
Definition of done (per task)
Section titled “Definition of done (per task)”- File edited or created correctly
-
npm run buildpasses - Committed with correct message format
- Corresponding GitHub issue referenced
BUG FIXES — Branch: fix/v0.9.0-bugs
Section titled “BUG FIXES — Branch: fix/v0.9.0-bugs”Task 1 — Fix sc commands triggering config/init prompts
Section titled “Task 1 — Fix sc commands triggering config/init prompts”Commit: fix: prevent sc help and other commands from triggering init prompts
File: src/sc.ts
The problem: Every sc command runs through a first-run check that prompts for scale tier and config if no config exists. Commands like sc help, sc --version, and sc --help should NEVER trigger config prompts.
Fix: Add an early return for info-only commands before any config check:
// At the top of the main command handler, before any config loading:const infoCommands = ["help", "--help", "-h", "--version", "-v", "version"];if (infoCommands.includes(args[0])) { // Handle these commands without loading config // sc help: call showHelp() directly // sc --version: print version directly return;}Also check src/index.ts for the same pattern in the create / sc create entry point. The --dry-run and --help flags should not trigger config prompts either.
Definition of done: sc help, sc --help, sc --version all work without any config prompts. Build passes.
Task 2 — Fix sc create argument parsing
Section titled “Task 2 — Fix sc create argument parsing”Commit: fix: prevent sc create from parsing "create" as a project name
File: src/index.ts (or wherever the argument parser for sc create lives)
The problem: Running sc create "test-project" creates TWO projects — one named “create” and one named “test-project.” The word “create” from the subcommand is being treated as a project name.
Fix: When the command is sc create, the first argument after create is the project name. The word create itself is the subcommand, not a project name. Update the argument parsing to skip the subcommand.
Check how args are split. If process.argv gives ["sc", "create", "test-project"], then:
args[0]= “create” (subcommand, skip)args[1]= “test-project” (project name)
If the binary is sc and the subcommand is create, only args after index 0 should be treated as the project name.
Also fix: The create binary alias (from package.json bin.create) should work the same way. create "test-project" should parse “test-project” as the only project name.
Definition of done: sc create "test" creates exactly one project named “test.” create "test" also creates exactly one project. Build passes.
Task 3 — Fix “middleware” → “enterprise” in scale tier prompt
Section titled “Task 3 — Fix “middleware” → “enterprise” in scale tier prompt”Commit: fix: rename middleware scale tier to enterprise
Files: Search all source files for “middleware”:
grep -rl "middleware" src/ templates/Replace every occurrence of “middleware” with “enterprise” in:
- Scale tier prompt options
- Any switch/case statements checking scale tier
- Any template references
- Help text
- README if applicable
Definition of done: Zero occurrences of “middleware” as a scale tier anywhere in source or templates. Build passes.
Task 4 — Add numbered options to all interactive prompts
Section titled “Task 4 — Add numbered options to all interactive prompts”Commit: feat: add numbered options to all interactive prompts
File: src/index.ts (or wherever prompts are defined)
Change all multi-option prompts from:
Scale tier [hobby / professional / enterprise] (hobby):To:
Scale tier (hobby): 1. hobby 2. professional 3. enterpriseChoice [1-3]:Apply to every prompt that has multiple options:
- Scale tier
- Frontend
- Database
- Hosting
- Git authorship
- Any other multi-choice prompts
User can type the number OR the word. Both should work.
Definition of done: All prompts show numbered options. Users can answer with number or name. Build passes.
Task 5 — Fix sc help build topic vs command precedence
Section titled “Task 5 — Fix sc help build topic vs command precedence”Commit: fix: prioritize topic over command in sc help lookups
File: src/scHelp.ts (or wherever help routing lives)
The problem: sc help build shows the command description instead of the topic guide because command lookup runs first.
Fix: When sc help [word] is called, check topics first, then fall back to commands. Topics are the detailed guides. Command descriptions are the one-liners shown in sc help (no argument).
Definition of done: sc help build shows the full topic guide. sc help (no args) still shows all commands with one-line descriptions. Build passes.
SC RULESET COMMAND — Branch: feature/v0.9.0-ruleset
Section titled “SC RULESET COMMAND — Branch: feature/v0.9.0-ruleset”Task 6 — Create sc ruleset command
Section titled “Task 6 — Create sc ruleset command”Commit: feat: add sc ruleset command for solo/team presets
File: Create src/scRuleset.ts
Interactive command that lets the operator configure branch protection presets:
$ sc ruleset
Current preset: solo
Available presets: 1. solo — 0 required approvals, CI optional, conversation resolution off 2. team — 1+ required approvals, CI must pass, conversation resolution required
Select preset [1-2]: 2
Team preset selected.
Required approvals (default 1): 2
Saving to project config...
Updated .scaffolder with: ruleset: team requiredApprovals: 2 requireCI: true requireConversationResolution: true
────────────────────────────────────────To apply these rules in GitHub:
1. Go to: https://github.com/[username]/[project]/settings/rules2. Open your "Protected Branches" ruleset (or create one)3. Set these rules: ✓ Require pull request before merging ✓ Required approvals: 2 ✓ Require status checks to pass (select your CI workflow) ✓ Require conversation resolution ✓ Restrict deletions ✓ Block force pushes4. Target branches: main, staging, dev5. Save
Export your ruleset as JSON for backup: Settings → Rules → Rulesets → Export────────────────────────────────────────Config fields added to .scaffolder:
{ "ruleset": "solo", "requiredApprovals": 0, "requireCI": false, "requireConversationResolution": false}Definition of done: sc ruleset runs interactively. Saves to .scaffolder. Prints clear GitHub instructions. Build passes.
Task 7 — Add sc ruleset slash command
Section titled “Task 7 — Add sc ruleset slash command”Commit: feat: add /sc-ruleset slash command
File: Create .claude/commands/sc-ruleset.md and templates/claude-commands/sc-ruleset.md
---description: Configure branch protection presets (solo/team)---
Run the ruleset configuration command:
```bashsc rulesetFollow the interactive prompts to select solo or team preset. After saving, apply the printed instructions in GitHub Settings → Rules → Rulesets.
**Definition of done:** `/sc-ruleset` available in Claude Code. Template copied to new projects. Build passes.
---
### Task 8 — Wire sc ruleset into sc init
**Commit:** `feat: set default ruleset preset during sc init`
**File:** `src/sc.ts` (handleInit function)
During `sc init`:- After the personal/team mode question- If team mode: default ruleset to "team", ask for required approvals (default 1)- If personal mode: default ruleset to "solo"- Save to global config (~/.scaffolder-config.json)
When `sc create` runs, copy the ruleset preset from global config into the new project's .scaffolder file.
**Definition of done:** `sc init` sets ruleset defaults. `sc create` inherits them. Build passes.
---
## SCALE-TIER WORKFLOW — Branch: feature/v0.9.0-scale-workflow
---
### Task 9 — Scale-tier-aware branch creation
**Commit:** `feat: branch creation based on scale tier`
**File:** `src/createGit.ts`
Current behavior: All projects get main, staging, dev.
New behavior based on scale tier:- **hobby:** main, dev only. No staging branch.- **professional:** main, staging, dev. (Current behavior.)- **enterprise:** main, staging, dev. (Same as professional — difference is in rulesets, not branches.)
Read scale tier from the project config passed through the create flow. Conditionally create staging:
```typescriptif (scaleTier !== "hobby") { run("git checkout -b staging main");}run("git checkout -b dev");Same logic in createGithub.ts for pushing:
if (scaleTier !== "hobby") { run("git push -u origin staging");}Definition of done: Hobby projects get main + dev. Professional/enterprise get main + staging + dev. Build passes.
Task 10 — Scale-tier-aware ruleset defaults
Section titled “Task 10 — Scale-tier-aware ruleset defaults”Commit: feat: set ruleset defaults based on scale tier at create time
File: src/createDocs.ts or wherever .scaffolder metadata is written
When writing the .scaffolder file during sc create, set ruleset defaults based on scale tier:
const rulesetDefaults = { hobby: { ruleset: "solo", requiredApprovals: 0, requireCI: false, requireConversationResolution: false }, professional: { ruleset: "solo", requiredApprovals: 0, requireCI: false, requireConversationResolution: false }, enterprise: { ruleset: "team", requiredApprovals: 1, requireCI: true, requireConversationResolution: true },};Hobby and professional default to solo (operator can upgrade with sc ruleset).
Enterprise defaults to team with CI required.
Definition of done: .scaffolder includes ruleset fields based on scale tier. Build passes.
Task 11 — Update STANDARDS.md template and docs for scale-tier workflow
Section titled “Task 11 — Update STANDARDS.md template and docs for scale-tier workflow”Commit: docs: document scale-tier workflow differences
File: templates/STANDARDS.md
Add a section after branch strategy:
## Workflow by scale tier
### Hobby- Branches: main, dev- Flow: feature → dev (PR) → main (PR)- No staging branch- No required approvals- CI optional- Good for: learning, personal projects, experiments
### Professional- Branches: main, staging, dev- Flow: feature → dev (PR) → staging (PR) → main (PR)- No required approvals by default (upgrade with `sc ruleset`)- Claude PR review recommended- Good for: solo professional work, small teams
### Enterprise- Branches: main, staging, dev- Flow: feature → dev (PR) → staging (PR) → main (PR)- Required approvals: 1+ (configurable)- CI must pass before merge- Conversation resolution required- Claude PR review enabled- Good for: team projects, client work, production systems
### Changing your workflow- Upgrade anytime: `sc ruleset`- This updates your local config and prints GitHub instructions- GitHub rulesets must be configured manually (automation coming soon)
### Branch flow rules (all tiers)- Feature branches merge to dev only — never to staging or main- dev → staging is a release decision — manual PR, manual merge- staging → main is a production decision — manual PR, manual merge- Code never creates PRs to staging or main- If a bug is found on staging: create fix/ branch from staging, PR to staging, then also PR to dev- After main is tagged: merge main back to dev to syncAlso update templates/CLAUDE.md branch strategy section to reference scale tiers:
## Branch strategyBranch structure depends on project scale tier (see STANDARDS.md for details).- [CODE_AI_NAME] always works on a feature or fix branch- [CODE_AI_NAME] never pushes to dev, staging, or main directly- [CODE_AI_NAME] creates PRs to dev only — never to staging or main- staging → main and dev → staging are operator decisionsDefinition of done: STANDARDS.md and CLAUDE.md document scale-tier workflows. All tiers documented. Build passes.
CLAUDE REVIEW — Branch: feature/v0.9.0-claude-review
Section titled “CLAUDE REVIEW — Branch: feature/v0.9.0-claude-review”Task 12 — Enable Claude review at professional+ by default
Section titled “Task 12 — Enable Claude review at professional+ by default”Commit: feat: enable Claude PR review by default at professional and enterprise tiers
File: src/createDocs.ts
Current behavior: claude-review.yml.disabled is copied to all projects.
New behavior:
- hobby: Copy as
.disabled(operator can enable manually) - professional: Copy as
claude-review.yml(active, but still needs API key setup) - enterprise: Copy as
claude-review.yml(active)
The file still needs the operator to add ANTHROPIC_API_KEY to GitHub secrets. But the workflow file itself is active — it just won’t run until the secret exists. GitHub Actions gracefully skip if the secret is missing.
Update the template header for the active version:
# Automated PR review with Claude Code## Setup required:# 1. Add your ANTHROPIC_API_KEY to GitHub repo secrets# 2. Run /install-github-app in Claude Code## Cost: Usage is billed per API call. Review current pricing at:# https://www.anthropic.com/pricing
name: Claude PR Reviewon: pull_request: types: [opened, synchronize] issue_comment: types: [created]# ... rest of workflow (uncommented)Also update printDryRun() to show the correct filename based on tier.
Definition of done: Hobby gets .disabled. Professional/enterprise get active .yml. Build passes.
RELEASE — Branch: feature/v0.9.0-release
Section titled “RELEASE — Branch: feature/v0.9.0-release”Task 13 — Version bump, CHANGELOG, migration, README, and release flow
Section titled “Task 13 — Version bump, CHANGELOG, migration, README, and release flow”Commit: chore: bump version to 0.9.0
Commit: docs: update CHANGELOG, README for v0.9.0
-
Bump package.json to 0.9.0
-
Update versions.json:
"latest": "0.9.0","0.9.0": { "breaking": false, "changes": [ "Fixed: sc help no longer triggers config prompts", "Fixed: sc create argument parsing — no more duplicate projects", "Fixed: middleware renamed to enterprise in scale tier", "Fixed: sc help topic vs command precedence", "Added: numbered options for all interactive prompts", "Added: sc ruleset command — solo/team presets with GitHub instructions", "Added: scale-tier-aware branch creation (hobby: no staging)", "Added: scale-tier-aware ruleset defaults", "Added: Claude PR review enabled by default at professional+ tier", "Added: workflow documentation by scale tier in STANDARDS.md" ]}-
Update CHANGELOG.md with full v0.9.0 entries
-
Create migration
src/migrations/v0.8.1-to-v0.9.0.ts:
export const migration = { fromVersion: "0.8.1", toVersion: "0.9.0", breaking: false, filesAdded: [], filesChanged: [ "CLAUDE.md", "STANDARDS.md", ".scaffolder", ], filesRemoved: [], instructions: "Scale-tier-aware workflows added. Run 'sc ruleset' to configure branch protection presets. Hobby projects no longer create staging branch.",};Register in migrations/index.ts.
-
Update README.md:
- Badge to v0.9.0
- Add “Workflow by scale tier” section
- Add “Branch protection” section
- Mention
sc rulesetin command reference - Update “What you get” for scale-tier-aware branches
-
Update STATUS.md, docs/ARCHITECTURE.md
-
Verify all feature branches are merged to dev:
- fix/v0.9.0-bugs ✓
- feature/v0.9.0-ruleset ✓
- feature/v0.9.0-scale-workflow ✓
- feature/v0.9.0-claude-review ✓
-
Merge feature/v0.9.0-release to dev
-
Test on dev:
npm run buildpassessc create "test-v090"with hobby tier → verify: main + dev only, no staging, .disabled reviewsc create "test-v090-pro"with professional tier → verify: main + staging + dev, active review ymlsc help→ no config promptsc help build→ topic guide, not command descriptionsc ruleset→ interactive flow works- Clean up test projects and repos
-
Update sessions/CURRENT.md
-
Push dev
STOP HERE. Code never touches staging or main.
Code never creates PRs to staging or main. Code never merges to staging or main. Code never tags releases.
Operator handles everything after dev:
- PR: dev → staging (operator creates and merges)
- Test on staging
- If staging bug: operator tells Code to create fix/ branch from staging → PR to staging AND dev
- PR: staging → main (operator creates and merges)
- Tag v0.9.0 on main
- Merge main back to dev (sync)
- Close milestone v0.9.0
Definition of done for Code: All feature branches merged to dev. Dev tested. sessions/CURRENT.md updated. Build clean. Report to operator that dev is ready for release.