Research: Frontmatter-Only Lane Management

Feature: 007-frontmatter-only-lane Date: 2025-12-17 Status: Complete

Executive Summary

Codebase exploration confirms the refactoring is well-scoped. Lane management flows through ~6 core modules with ~20 functions directly depending on directory-based lane detection. The architecture supports clean separation of concerns, making the transition to frontmatter-only lanes straightforward.

Key Decisions

D-001: Command Rename (move → update)

Decision: Rename the move command to update

Rationale:

  • "Move" implies file relocation, which no longer happens
  • "Update" accurately describes the operation: modifying frontmatter metadata
  • Clean semantic break reinforces the new paradigm

Alternatives Rejected:

  • Keep "move" name: Confusing since no files move
  • "set-lane": Too verbose, breaks existing muscle memory partially

D-002: No Backwards Compatibility

Decision: Clean break - new format only, require migration first

Rationale:

  • Hybrid mode adds significant complexity
  • Two code paths = two sets of bugs
  • Clear migration path via spec-kitty upgrade
  • User preference for clean breaks

Alternatives Rejected:

  • Support both formats: Complexity not worth transitional convenience
  • Auto-migrate on first command: Too surprising, could cause data issues

D-003: All-at-Once Migration

Decision: Single spec-kitty upgrade migrates main repo + all worktrees

Rationale:

  • Consistent state across entire project
  • No confusion about which features are migrated
  • Single confirmation prompt for entire operation
  • Idempotent design allows safe re-runs

Alternatives Rejected:

  • Per-feature migration: More prompts, inconsistent state possible
  • Per-worktree migration: Complex, worktrees should track main repo format

D-004: Default Lane for Missing Field

Decision: Default to "planned" with warning when lane: field missing

Rationale:

  • "Planned" is the safest default (nothing lost, nothing in progress)
  • Warning ensures visibility of the issue
  • Matches current template behavior (new WPs start as planned)

Alternatives Rejected:

  • Error and refuse: Too strict for minor data quality issues
  • Default to "doing": Could cause incorrect status assumptions

Codebase Analysis

Current Architecture

Lane management is implemented across these key locations:

ModuleLocationRole
Tasks CLIscripts/tasks/tasks_cli.pyUser-facing lane commands
Task Helpersscripts/tasks/task_helpers.pyWP location, frontmatter parsing
Tasks Supportsrc/specify_cli/tasks_support.pyDuplicate helper functions
Dashboard Scannersrc/specify_cli/dashboard/scanner.pyLane visualization
Metadata Validationsrc/specify_cli/task_metadata_validation.pyLane mismatch detection
Acceptancesrc/specify_cli/acceptance.pyLane-based acceptance checks

Directory-Based Lane Detection Points

1. locate_work_package() in task_helpers.py:289-328

  • Iterates tasks_root.iterdir() expecting lane subdirectories
  • Will change to: Scan flat tasks/, return lane from frontmatter

2. stage_move() in tasks_cli.py:51-87

  • Builds target_dir = tasks / target_lane path
  • Performs shutil.move() between directories
  • Will change to: Update frontmatter only, no file movement

3. scan_feature_kanban() in scanner.py:293-370

  • Loops through for lane in lanes.keys() with lane_dir = tasks_dir / lane
  • Will change to: Scan flat tasks/, group results by frontmatter lane:

4. detect_lane_mismatch() in task_metadata_validation.py:34-76

  • Extracts expected lane from file path
  • Will change to: Remove entirely (no directory to mismatch)

5. scan_all_features() in scanner.py:259-267

  • Counts items per lane directory
  • Will change to: Count by frontmatter field

LANES Constant Locations

The LANES tuple is defined in multiple places (sync required):

  • scripts/tasks/task_helpers.py:14
  • src/specify_cli/tasks_support.py:14

Recommendation: Consider consolidating to single source, imported by both modules.

WP Frontmatter Structure

Current WP files already include the lane: field:

---
work_package_id: "WP01"
title: "Work Package Title"
lane: "done"              # Single source of truth (new design)
phase: "Phase 1"
assignee: ""
activity_log: |
  - 2025-01-16T12:45:07Z – system – lane=planned – Created
---

Key Finding: No schema changes needed - the lane: field already exists and is populated. The change is purely about which mechanism is authoritative.

Risk Assessment

RiskLikelihoodImpactMitigation
Migration data lossLowHighIdempotent design, confirmation prompt, backup recommendation
Test suite breakageHighMediumSystematic test updates planned, tracked in tasks
Concurrent edit conflictsLowLowNo files move, standard git conflict resolution
Dashboard rendering issuesMediumMediumTest with real data before release

Open Questions

All questions resolved during planning interrogation:

  • Command naming: Confirmed update
  • Backwards compatibility: Confirmed none (clean break)
  • Migration scope: Confirmed all-at-once

Evidence Sources

IDSourceTypeRelevance
E-001scripts/tasks/tasks_cli.pyCodebasePrimary move command implementation
E-002scripts/tasks/task_helpers.pyCodebaseWP location logic
E-003src/specify_cli/dashboard/scanner.pyCodebaseDashboard lane rendering
E-004src/specify_cli/task_metadata_validation.pyCodebaseLane mismatch detection
E-005tests/test_tasks_cli_commands.pyCodebaseExisting test patterns
E-006User planning inputStakeholderClean break preference confirmed