jettypod 4.4.45 → 4.4.47

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/lib/database.js CHANGED
@@ -203,6 +203,39 @@ function initSchema() {
203
203
  }
204
204
  });
205
205
 
206
+ db.run(`
207
+ CREATE TABLE IF NOT EXISTS skill_executions (
208
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
209
+ work_item_id INTEGER NOT NULL,
210
+ skill_name TEXT NOT NULL,
211
+ status TEXT DEFAULT 'in_progress',
212
+ step_reached INTEGER DEFAULT 1,
213
+ context_json TEXT,
214
+ started_at DATETIME DEFAULT CURRENT_TIMESTAMP,
215
+ completed_at DATETIME,
216
+ FOREIGN KEY (work_item_id) REFERENCES work_items(id)
217
+ )
218
+ `, (err) => {
219
+ if (err) {
220
+ throw new Error(`Failed to create skill_executions table: ${err.message}`);
221
+ }
222
+ });
223
+
224
+ db.run(`
225
+ CREATE TABLE IF NOT EXISTS workflow_gates (
226
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
227
+ work_item_id INTEGER NOT NULL,
228
+ gate_name TEXT NOT NULL,
229
+ passed_at DATETIME,
230
+ UNIQUE(work_item_id, gate_name),
231
+ FOREIGN KEY (work_item_id) REFERENCES work_items(id)
232
+ )
233
+ `, (err) => {
234
+ if (err) {
235
+ throw new Error(`Failed to create workflow_gates table: ${err.message}`);
236
+ }
237
+ });
238
+
206
239
  // Migrations: Add columns if they don't exist (for databases created before these columns were in base schema)
207
240
  const handleAlterError = (columnName) => (err) => {
208
241
  if (err && !err.message.includes('duplicate column')) {
@@ -1629,10 +1629,82 @@ async function mergeWork(options = {}) {
1629
1629
  }
1630
1630
  }
1631
1631
 
1632
+ /**
1633
+ * Create a worktree for writing BDD tests for a feature
1634
+ * @param {number} featureId - Feature ID to create test worktree for
1635
+ * @returns {Promise<Object>} Worktree info with path and branch
1636
+ * @throws {Error} If feature not found or not in correct phase
1637
+ */
1638
+ async function testsWork(featureId) {
1639
+ if (!featureId || isNaN(featureId) || featureId < 1) {
1640
+ return Promise.reject(new Error('Invalid feature ID'));
1641
+ }
1642
+
1643
+ const paths = getPaths();
1644
+
1645
+ if (!fs.existsSync(paths.jettypodDir)) {
1646
+ return Promise.reject(new Error('JettyPod not initialized. Run: jettypod init'));
1647
+ }
1648
+
1649
+ if (!fs.existsSync(paths.dbPath)) {
1650
+ return Promise.reject(new Error('Work database not found. Run: jettypod init'));
1651
+ }
1652
+
1653
+ const db = getDb();
1654
+
1655
+ return new Promise((resolve, reject) => {
1656
+ // Get feature work item
1657
+ db.get(
1658
+ `SELECT * FROM work_items WHERE id = ? AND type = 'feature'`,
1659
+ [featureId],
1660
+ async (err, feature) => {
1661
+ if (err) {
1662
+ return reject(new Error(`Database error: ${err.message}`));
1663
+ }
1664
+
1665
+ if (!feature) {
1666
+ return reject(new Error(`Feature #${featureId} not found`));
1667
+ }
1668
+
1669
+ // Create worktree with tests/ prefix
1670
+ try {
1671
+ const gitRoot = getGitRoot();
1672
+ const worktreeResult = await worktreeManager.createWorktree(feature, {
1673
+ repoPath: gitRoot,
1674
+ branchPrefix: 'tests/feature',
1675
+ pathPrefix: 'tests-'
1676
+ });
1677
+
1678
+ // Set as current work
1679
+ setCurrentWork({
1680
+ id: feature.id,
1681
+ type: feature.type,
1682
+ title: feature.title,
1683
+ status: feature.status || 'in_progress',
1684
+ worktreePath: worktreeResult.worktree_path,
1685
+ branchName: worktreeResult.branch_name
1686
+ });
1687
+
1688
+ console.log(`✅ Created test worktree: ${worktreeResult.worktree_path}`);
1689
+ console.log(`📁 IMPORTANT: Use absolute paths for file operations:`);
1690
+ console.log(` ${worktreeResult.worktree_path}/features/your-feature.feature (correct)`);
1691
+ console.log(` features/your-feature.feature (wrong - creates in main repo)`);
1692
+ console.log(`\nWorking on tests for: [#${feature.id}] ${feature.title}`);
1693
+
1694
+ resolve(worktreeResult);
1695
+ } catch (worktreeErr) {
1696
+ reject(new Error(`Failed to create test worktree: ${worktreeErr.message}`));
1697
+ }
1698
+ }
1699
+ );
1700
+ });
1701
+ }
1702
+
1632
1703
  module.exports = {
1633
1704
  startWork,
1634
1705
  stopWork,
1635
1706
  getCurrentWork,
1636
1707
  cleanupWorktrees,
1637
- mergeWork
1708
+ mergeWork,
1709
+ testsWork
1638
1710
  };
@@ -29,6 +29,8 @@ const VALID_STATUSES = ['active', 'merging', 'cleanup_pending', 'corrupted'];
29
29
  * @param {Object} options - Optional configuration
30
30
  * @param {string} options.repoPath - Path to git repository (defaults to process.cwd())
31
31
  * @param {Object} options.db - Database connection (defaults to global database)
32
+ * @param {string} options.branchPrefix - Branch prefix (defaults to 'feature/work')
33
+ * @param {string} options.pathPrefix - Worktree path prefix (defaults to '')
32
34
  * @returns {Promise<Object>} Worktree record with id, work_item_id, branch_name, worktree_path, status
33
35
  */
34
36
  async function createWorktree(workItem, options = {}) {
@@ -85,9 +87,11 @@ async function createWorktree(workItem, options = {}) {
85
87
 
86
88
  // Generate branch name and worktree path
87
89
  const titleSlug = slugify(workItem.title || 'item');
88
- const branchName = `feature/work-${workItem.id}-${titleSlug}`;
90
+ const branchPrefix = options.branchPrefix || 'feature/work';
91
+ const pathPrefix = options.pathPrefix || '';
92
+ const branchName = `${branchPrefix}-${workItem.id}-${titleSlug}`;
89
93
  const worktreeBasePath = path.join(gitRoot, '.jettypod-work');
90
- const worktreePath = path.join(worktreeBasePath, `${workItem.id}-${titleSlug}`);
94
+ const worktreePath = path.join(worktreeBasePath, `${pathPrefix}${workItem.id}-${titleSlug}`);
91
95
 
92
96
  let worktreeId = null;
93
97
  let branchCreated = false;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "jettypod",
3
- "version": "4.4.45",
3
+ "version": "4.4.47",
4
4
  "description": "AI-powered development workflow manager with TDD, BDD, and automatic test generation",
5
5
  "main": "jettypod.js",
6
6
  "bin": {
@@ -78,6 +78,14 @@ Implementation Plan:
78
78
 
79
79
  **Your task:** Create an isolated worktree for this chore.
80
80
 
81
+ **🚫 FORBIDDEN: Manual Git Worktree Commands**
82
+ ```
83
+ ❌ git worktree add ...
84
+ ❌ git checkout -b feature/...
85
+ ❌ git branch feature/...
86
+ ```
87
+ **ALWAYS use `jettypod work start`** - it handles branch naming, path conventions, database tracking, and cleanup. Manual git commands will create orphaned worktrees that break the merge workflow.
88
+
81
89
  ```bash
82
90
  jettypod work start [chore-id]
83
91
  ```
@@ -13,20 +13,23 @@ When this skill is activated, you are helping discover the best approach for a f
13
13
 
14
14
  ## 🔑 Critical Command Distinction
15
15
 
16
- **Two different commands, two different purposes:**
16
+ **Four different commands, four different purposes:**
17
17
 
18
18
  | Command | Used For | When | Phase |
19
19
  |---------|----------|------|-------|
20
- | `work implement <feature-id>` | Transition feature to implementation phase | During feature planning (Step 8B) | Feature Planning |
21
- | `work start <chore-id>` | Start implementing a specific chore | After feature planning complete (Step 8D) | Speed Mode |
20
+ | `work implement <feature-id>` | Transition feature to implementation phase | After chores created (Step 8C) | Feature Planning |
21
+ | `work tests start <feature-id>` | Create worktree for test authoring | After transition (Step 8D) | Feature Planning |
22
+ | `work tests merge <feature-id>` | Merge tests to main, cleanup worktree | After tests validated (Step 8D) | Feature Planning |
23
+ | `work start <chore-id>` | Start implementing a specific chore | After tests merged (Step 8E) | Speed Mode |
22
24
 
23
- **CRITICAL:** Both commands are run by **Claude**, not the user. The distinction is:
24
- - `work implement` = Ends feature planning, creates chores
25
- - `work start` = Creates worktree/branch for chore (does NOT auto-invoke speed-mode)
25
+ **CRITICAL:** All commands are run by **Claude**, not the user. The distinction is:
26
+ - `work implement` = Ends feature planning, transitions to implementation phase
27
+ - `work tests start/merge` = Write and land BDD tests in isolated worktree
28
+ - `work start` = Creates worktree/branch for chore implementation
26
29
 
27
- **🛑 STOP GATE:** DO NOT run `work start` until Step 8D. If you're in Steps 1-8C, use `work implement` only.
30
+ **🛑 STOP GATE:** DO NOT run `work start` until Step 8E. Tests must be merged to main first.
28
31
 
29
- **🛑 HANDOFF REQUIREMENT:** After `work start`, you MUST invoke speed-mode using the Skill tool. See Step 8D.
32
+ **🛑 HANDOFF REQUIREMENT:** After `work start`, you MUST invoke speed-mode using the Skill tool. See Step 8E.
30
33
 
31
34
  ---
32
35
 
@@ -224,9 +227,9 @@ Example:
224
227
 
225
228
  **WAIT for user to confirm or adjust the integration contract.**
226
229
 
227
- #### Step 6B: Generate BDD Scenarios AND Step Definitions
230
+ #### Step 6B: Propose BDD Scenarios (DO NOT WRITE YET)
228
231
 
229
- **CRITICAL:** BDD scenarios and step definitions must ALWAYS be created together. Never create scenarios without step definitions.
232
+ **CRITICAL:** Do NOT write files yet. Display the proposed scenarios for user confirmation. Files will be written in Step 8D inside an isolated worktree.
230
233
 
231
234
  **Feature slug:** Derive `FEATURE_SLUG` from the feature title:
232
235
  - Lowercase
@@ -234,43 +237,79 @@ Example:
234
237
  - Remove special characters
235
238
  - Examples: "Email Password Login" → "email-password-login", "User's Profile (v2)" → "users-profile-v2"
236
239
 
237
- Based on chosen approach, generate:
240
+ Based on chosen approach, **display** the proposed scenarios to the user:
238
241
 
239
- **A. Scenario file** at `features/[feature-slug].feature` using Write tool:
242
+ ```
243
+ 📋 Proposed BDD Scenarios
240
244
 
241
- 1. **Create file** at `features/[feature-slug].feature` using Write tool
242
- 2. **FIRST scenario MUST be the Integration Scenario** from Step 6A (proves reachability)
243
- 3. **Include all "make it work" scenarios**:
244
- - All success paths - required functionality AND optional features
245
- - Multiple valid workflows if the feature supports them
246
- - Success variations (different outcomes that are all correct)
247
- - NO error handling scenarios (added in stable mode)
248
- - NO validation failures (added in stable mode)
249
- - NO security/compliance scenarios (added in production mode)
245
+ **Feature file:** features/[feature-slug].feature
246
+ **Step definitions:** features/step_definitions/[feature-slug].steps.js
247
+ ```
250
248
 
251
- **B. Step definitions file** at `features/step_definitions/[feature-slug].steps.js` using Write tool:
249
+ Then show the full Gherkin content:
252
250
 
253
- 1. **Create file** at `features/step_definitions/[feature-slug].steps.js`
254
- 2. **Implement all Given/When/Then steps** from the scenarios
255
- 3. **Follow existing patterns** - check other `.steps.js` files for conventions
256
- 4. **Include**:
257
- - Test environment setup/cleanup
258
- - All Given steps (setup state)
259
- - All When steps (execute actions)
260
- - All Then steps (verify outcomes)
251
+ ```gherkin
252
+ Feature: [Feature Name]
253
+ [Brief description based on chosen UX approach]
261
254
 
262
- **C. Update database** with scenario file path (run from project root):
255
+ Epic: [Epic name if applicable]
256
+ Approach: [Chosen approach name]
263
257
 
264
- ```bash
265
- sqlite3 .jettypod/work.db "UPDATE work_items SET scenario_file = 'features/${FEATURE_SLUG}.feature' WHERE id = ${FEATURE_ID}"
258
+ # Integration Contract:
259
+ # Entry Point: [from Step 6A]
260
+ # Caller Code: [from Step 6A]
261
+
262
+ # INTEGRATION SCENARIO (REQUIRED - proves feature is reachable)
263
+ Scenario: User can reach [feature] from [entry point]
264
+ Given I am on [existing entry point users can access]
265
+ When I [navigate/click/invoke to reach the feature]
266
+ Then I [see/access the feature]
267
+
268
+ # FEATURE SCENARIOS (required + optional functionality)
269
+ Scenario: [Core functionality - required workflow]
270
+ Given [initial state]
271
+ When [user takes main action]
272
+ Then [expected successful outcome]
273
+ And [observable UI/system state change]
274
+
275
+ Scenario: [Optional feature 1 - if applicable]
276
+ Given [initial state]
277
+ When [user uses optional feature]
278
+ Then [feature works correctly]
279
+
280
+ # SPEED MODE: All success scenarios above (integration + required + optional)
281
+ # STABLE MODE: Will add error handling, validation failures, edge cases
266
282
  ```
267
283
 
268
- Replace `${FEATURE_SLUG}` and `${FEATURE_ID}` with actual values. Example:
269
- ```bash
270
- sqlite3 .jettypod/work.db "UPDATE work_items SET scenario_file = 'features/email-password-login.feature' WHERE id = 42"
284
+ Then list the step definitions that will be created:
285
+
286
+ ```
287
+ **Step definitions to implement:**
288
+ • Given I am on [entry point] - [brief implementation note]
289
+ • When I [action] - [brief implementation note]
290
+ • Then I [outcome] - [brief implementation note]
291
+ [etc.]
292
+
293
+ Does this capture the feature correctly? Any scenarios to add/change?
271
294
  ```
272
295
 
273
- **Proceed to Step 6.5.**
296
+ **Scenario content requirements:**
297
+ - **FIRST scenario MUST be the Integration Scenario** from Step 6A (proves reachability)
298
+ - **Include all "make it work" scenarios**:
299
+ - All success paths - required functionality AND optional features
300
+ - Multiple valid workflows if the feature supports them
301
+ - Success variations (different outcomes that are all correct)
302
+ - NO error handling scenarios (added in stable mode)
303
+ - NO validation failures (added in stable mode)
304
+ - NO security/compliance scenarios (added in production mode)
305
+
306
+ **WAIT for user confirmation.**
307
+
308
+ - If user confirms → Proceed to Step 7
309
+ - If user requests changes → Revise scenarios and display again
310
+ - **Store the confirmed scenarios in memory** - you'll write them in Step 8D
311
+
312
+ **Proceed to Step 7.**
274
313
 
275
314
  **Template for speed mode (make it work):**
276
315
 
@@ -395,102 +434,9 @@ Scenario: Prevent unauthorized access
395
434
 
396
435
  </details>
397
436
 
398
- ### Step 6.5: Validate BDD Infrastructure
399
-
400
- **CRITICAL:** After creating both scenario and step definition files, validate them with cucumber dry-run to catch errors immediately.
401
-
402
- **Run this command** (replace `${FEATURE_SLUG}` with actual slug):
403
-
404
- ```bash
405
- npx cucumber-js --dry-run features/${FEATURE_SLUG}.feature
406
- ```
407
-
408
- Example:
409
- ```bash
410
- npx cucumber-js --dry-run features/email-password-login.feature
411
- ```
412
-
413
- **What the output means:**
414
-
415
- ✅ **Success** - No errors, all steps have definitions:
416
- ```
417
- 0 scenarios
418
- 0 steps
419
- ```
420
- (Dry-run doesn't execute, so 0 is correct)
421
-
422
- ❌ **Undefined steps** - Missing step definitions:
423
- ```
424
- Undefined. Implement with the following snippet:
425
- Given('I am on the login page', function () {
426
- ...
427
- });
428
- ```
429
- → Add the missing step definition to your `.steps.js` file
430
-
431
- ❌ **Syntax error** - Invalid Gherkin:
432
- ```
433
- Parse error in features/foo.feature
434
- ```
435
- → Fix the feature file syntax
436
-
437
- ❌ **Duplicate steps** - Multiple definitions match:
438
- ```
439
- Multiple step definitions match
440
- ```
441
- → Remove or rename one of the duplicate step definitions
442
-
443
- **If validation fails:**
444
- 1. Read the error message carefully
445
- 2. Fix the step definitions or scenario file
446
- 3. Re-run the dry-run command
447
- 4. **Loop until validation passes** - do NOT proceed to Step 7 until green
448
-
449
- **If validation succeeds:**
450
- Display: "✅ BDD infrastructure validated - all steps have definitions"
451
-
452
- **Proceed to Step 6.6.**
453
-
454
- **Note:** Unit tests are created during speed mode implementation, not during feature planning. Feature planning focuses on BDD scenarios (user experience); speed mode handles unit tests (implementation details).
455
-
456
- ### Step 6.6: Commit BDD Files to Main
457
-
458
- **CRITICAL:** The BDD files must be committed to main BEFORE creating worktrees. If you skip this step, worktrees won't have the scenario files and speed-mode will fail.
459
-
460
- **Commit the BDD files:**
461
-
462
- ```bash
463
- git add features/${FEATURE_SLUG}.feature features/steps/${FEATURE_SLUG}.* features/step_definitions/${FEATURE_SLUG}.*
464
- git commit -m "test: Add BDD scenarios for ${FEATURE_TITLE}
465
-
466
- - Feature file: features/${FEATURE_SLUG}.feature
467
- - Step definitions for speed mode scenarios"
468
-
469
- git push
470
- ```
471
-
472
- Replace `${FEATURE_SLUG}` and `${FEATURE_TITLE}` with actual values. Example:
473
- ```bash
474
- git add features/email-password-login.feature features/steps/email-password-login.* features/step_definitions/email-password-login.*
475
- git commit -m "test: Add BDD scenarios for Email Password Login
476
-
477
- - Feature file: features/email-password-login.feature
478
- - Step definitions for speed mode scenarios"
479
-
480
- git push
481
- ```
482
-
483
- **Why this matters:**
484
- - Worktrees are created from the current branch (usually main)
485
- - If BDD files aren't committed, they won't exist in the worktree
486
- - Speed-mode will fail trying to run tests against non-existent files
487
- - **Push is required** so other assistants/machines have the latest main
488
-
489
- **Proceed to Step 7.**
490
-
491
437
  ### Step 7: Propose Speed Mode Chores
492
438
 
493
- **CRITICAL:** After BDD validation passes, analyze the codebase and propose technical implementation chores. **DO NOT CREATE CHORES YET** - the feature must transition to implementation mode first (Step 8).
439
+ **CRITICAL:** After user confirms the BDD scenarios, analyze the codebase and propose technical implementation chores. **DO NOT CREATE CHORES YET** - the feature must transition to implementation mode first (Step 8).
494
440
 
495
441
  **Your analysis should consider:**
496
442
  - The BDD scenarios (integration + all success paths)
@@ -633,6 +579,147 @@ After successful transition, display:
633
579
  ✅ Feature transitioned to implementation phase
634
580
  ✅ Created X chores for speed mode
635
581
 
582
+ Now I'll write the BDD tests in an isolated worktree...
583
+ ```
584
+
585
+ **Proceed to Step 8D.**
586
+
587
+ #### Step 8D: Write Tests in Isolated Worktree
588
+
589
+ **CRITICAL:** Tests are written in an isolated worktree, not directly on main. This ensures agent failures don't leave uncommitted garbage on main.
590
+
591
+ **🚫 FORBIDDEN: Manual Git Worktree Commands**
592
+ ```
593
+ ❌ git worktree add ...
594
+ ❌ git checkout -b tests/...
595
+ ❌ git branch tests/...
596
+ ```
597
+ **ALWAYS use jettypod commands** - they handle branch naming, path conventions, database tracking, and cleanup. Manual git commands will create orphaned worktrees that break the merge workflow.
598
+
599
+ **Sub-step 1: Create test worktree**
600
+
601
+ ```bash
602
+ jettypod work tests start ${FEATURE_ID}
603
+ ```
604
+
605
+ This creates:
606
+ - Worktree at `.jettypod-work/tests-<id>-<slug>/`
607
+ - Branch `tests/feature-<id>-<slug>`
608
+
609
+ **Capture the worktree path from output** - you'll need it for file operations.
610
+
611
+ Example output:
612
+ ```
613
+ ✅ Created test worktree: /path/to/.jettypod-work/tests-42-email-login
614
+ Branch: tests/feature-42-email-login
615
+
616
+ Write your BDD files to:
617
+ <worktree>/features/email-login.feature
618
+ <worktree>/features/step_definitions/email-login.steps.js
619
+
620
+ When done, run: jettypod work tests merge 42
621
+ ```
622
+
623
+ **🛑 STOP AND CHECK:** Verify worktree was created successfully. If you see an error, investigate before continuing.
624
+
625
+ **Sub-step 2: Write BDD files in the worktree**
626
+
627
+ Using the scenarios you confirmed in Step 6B, write the files using **absolute paths to the worktree**:
628
+
629
+ **A. Write scenario file** using Write tool:
630
+ ```
631
+ <worktree_path>/features/${FEATURE_SLUG}.feature
632
+ ```
633
+
634
+ **B. Write step definitions file** using Write tool:
635
+ ```
636
+ <worktree_path>/features/step_definitions/${FEATURE_SLUG}.steps.js
637
+ ```
638
+
639
+ **Step definition requirements:**
640
+ 1. Implement all Given/When/Then steps from the scenarios
641
+ 2. Follow existing patterns - check other `.steps.js` files for conventions
642
+ 3. Include test environment setup/cleanup
643
+ 4. All Given steps (setup state)
644
+ 5. All When steps (execute actions)
645
+ 6. All Then steps (verify outcomes)
646
+
647
+ **Sub-step 3: Validate BDD infrastructure**
648
+
649
+ Run cucumber dry-run **from within the worktree**:
650
+
651
+ ```bash
652
+ cd <worktree_path> && npx cucumber-js --dry-run features/${FEATURE_SLUG}.feature
653
+ ```
654
+
655
+ **What the output means:**
656
+
657
+ ✅ **Success** - No errors, all steps have definitions:
658
+ ```
659
+ 0 scenarios
660
+ 0 steps
661
+ ```
662
+ (Dry-run doesn't execute, so 0 is correct)
663
+
664
+ ❌ **Undefined steps** - Missing step definitions:
665
+ ```
666
+ Undefined. Implement with the following snippet:
667
+ Given('I am on the login page', function () {
668
+ ...
669
+ });
670
+ ```
671
+ → Add the missing step definition to your `.steps.js` file
672
+
673
+ ❌ **Syntax error** - Invalid Gherkin:
674
+ ```
675
+ Parse error in features/foo.feature
676
+ ```
677
+ → Fix the feature file syntax
678
+
679
+ ❌ **Duplicate steps** - Multiple definitions match:
680
+ ```
681
+ Multiple step definitions match
682
+ ```
683
+ → Remove or rename one of the duplicate step definitions
684
+
685
+ **If validation fails:**
686
+ 1. Read the error message carefully
687
+ 2. Fix the step definitions or scenario file **in the worktree**
688
+ 3. Re-run the dry-run command
689
+ 4. **Loop until validation passes** - do NOT proceed until green
690
+
691
+ **If validation succeeds:**
692
+ Display: "✅ BDD infrastructure validated - all steps have definitions"
693
+
694
+ **Sub-step 4: Update database with scenario file path**
695
+
696
+ ```bash
697
+ sqlite3 .jettypod/work.db "UPDATE work_items SET scenario_file = 'features/${FEATURE_SLUG}.feature' WHERE id = ${FEATURE_ID}"
698
+ ```
699
+
700
+ **Sub-step 5: Merge tests to main**
701
+
702
+ ```bash
703
+ jettypod work tests merge ${FEATURE_ID}
704
+ ```
705
+
706
+ This will:
707
+ - Commit changes in the worktree
708
+ - Merge to main
709
+ - Push to remote
710
+ - Clean up the worktree
711
+
712
+ **🛑 STOP AND CHECK:** Verify merge succeeded:
713
+ - ✅ "Tests merged to main" → Proceed to Step 8E
714
+ - ❌ Error → Investigate, worktree still exists for debugging
715
+
716
+ **After successful merge, display:**
717
+
718
+ ```
719
+ ✅ Feature transitioned to implementation phase
720
+ ✅ Created X chores for speed mode
721
+ ✅ BDD tests merged to main
722
+
636
723
  ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
637
724
  🎯 Feature Planning Complete!
638
725
  ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
@@ -648,9 +735,11 @@ After successful transition, display:
648
735
  Start this one? [yes / pick different / done for now]
649
736
  ```
650
737
 
651
- #### Step 8D: Start First Chore
738
+ **Proceed to Step 8E.**
739
+
740
+ #### Step 8E: Start First Chore
652
741
 
653
- **Feature planning is now complete.** The feature has been transitioned to implementation phase and chores are ready.
742
+ **Feature planning is now complete.** The feature has been transitioned to implementation phase, tests are on main, and chores are ready.
654
743
 
655
744
  The completion message above already includes your recommendation. Now:
656
745
 
@@ -675,6 +764,14 @@ End feature-planning skill without starting a chore. Do NOT invoke speed-mode.
675
764
 
676
765
  **After user picks a chore, execute these steps IN ORDER:**
677
766
 
767
+ **🚫 FORBIDDEN: Manual Git Worktree Commands**
768
+ ```
769
+ ❌ git worktree add ...
770
+ ❌ git checkout -b feature/...
771
+ ❌ git branch feature/...
772
+ ```
773
+ **ALWAYS use `jettypod work start`** - it handles branch naming, path conventions, database tracking, and cleanup. Manual git commands will create orphaned worktrees that break the merge workflow.
774
+
678
775
  **Step 1: Start the chore (creates worktree and branch):**
679
776
  ```bash
680
777
  jettypod work start [chore-id]
@@ -763,14 +860,15 @@ Before completing feature planning, ensure:
763
860
  - [ ] Exactly 3 approaches suggested
764
861
  - [ ] Winner chosen (with prototypes or without)
765
862
  - [ ] **Integration Contract defined** (entry point, caller code, integration scenario)
766
- - [ ] **Integration Scenario is FIRST scenario** in feature file
767
- - [ ] BDD scenarios written (integration + all success paths)
768
- - [ ] Step definitions written for ALL scenario steps
769
- - [ ] Scenarios file exists at `features/[feature-slug].feature`
770
- - [ ] Step definitions file exists at `features/step_definitions/[feature-slug].steps.js`
771
- - [ ] BDD infrastructure validated with dry-run (Step 6.5)
772
- - [ ] Feature transitioned to implementation with `work implement`
773
- - [ ] **At least one Integration Chore created** (wires feature into app)
774
- - [ ] Speed mode chores created
775
- - [ ] First chore started with `work start [chore-id]` (Step 8D)
776
- - [ ] **Speed-mode skill invoked using Skill tool** (Step 8D)
863
+ - [ ] **Integration Scenario is FIRST scenario** in proposed scenarios
864
+ - [ ] BDD scenarios **proposed and confirmed** by user (Step 6B)
865
+ - [ ] **At least one Integration Chore proposed** (wires feature into app)
866
+ - [ ] Speed mode chores proposed and confirmed (Step 7)
867
+ - [ ] Chores created in database (Step 8B)
868
+ - [ ] Feature transitioned to implementation with `work implement` (Step 8C)
869
+ - [ ] **Test worktree created** with `work tests start` (Step 8D)
870
+ - [ ] **BDD files written** in worktree (Step 8D)
871
+ - [ ] **BDD infrastructure validated** with dry-run (Step 8D)
872
+ - [ ] **Tests merged to main** with `work tests merge` (Step 8D)
873
+ - [ ] First chore started with `work start [chore-id]` (Step 8E)
874
+ - [ ] **Speed-mode skill invoked using Skill tool** (Step 8E)