diff --git a/CHANGELOG.md b/CHANGELOG.md
index a71e1ff..172bfd2 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -136,21 +136,20 @@ Matches or exceeds industry standards of kubectl, terraform, and gh CLI:
- Conflict detection and resolution workflow
- TestPullService_ConflictResolvedWithForce test
- **Milestone 1**: Canonical markdown schema and tooling
- - Parser rejection of legacy # STORY: format
- - ticketr migrate command with dry-run and --write modes
- - 11 new tests (3 parser + 7 migration + 1 service)
- - docs/migration-guide.md (175 lines)
+ - Parser rejection of `# STORY:` heading with actionable error
+ - Manual update guidance documented in README/WORKFLOW
+ - 4 new tests (parser rejection cases + service guardrail)
- examples/README.md (155 lines)
- **Milestone 0**: Repository recon and standards alignment
- Canonical # TICKET: format established
- - Legacy # STORY: format deprecated with clear errors
- - testdata/legacy_story/ fixtures for regression tests
+ - `# STORY:` heading rejected with clear errors
+ - testdata/unsupported_story/ fixtures for regression tests
- docs/README.md documenting test strategy
### Changed
- Renamed from jira-story-creator to ticketr
- All examples migrated to canonical # TICKET: format
-- Enhanced README with migration guidance
+- Enhanced README with schema guidance
### Fixed
- Spurious change detection from non-deterministic map iteration
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index 47aaed9..a989f57 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -51,9 +51,9 @@ internal/
│ ├── jira/ # JIRA API integration
│ └── filesystem/ # Markdown file I/O
├── parser/ # Markdown parser
+├── renderer/ # Markdown rendering utilities
├── state/ # State management (.ticketr.state)
-├── logging/ # File logging
-└── migration/ # Legacy format migration
+└── logging/ # File logging
```
**Key principles:**
@@ -182,15 +182,14 @@ bash tests/smoke/smoke_test.sh
```
**Scenarios tested:**
-1. Legacy file migration
-2. Push dry-run validation
-3. Pull with missing file
-4. State file creation and persistence
-5. Log file creation
-6. Help command functionality
-7. Concurrent file operations safety
+1. Push dry-run validation
+2. Pull with missing file
+3. State file creation and persistence
+4. Log file creation
+5. Help command functionality
+6. Concurrent file operations safety
-**Expected:** 7/7 scenarios passing, 13/13 checks passing
+**Expected:** 6/6 scenarios passing, 12/12 checks passing
See [`tests/smoke/README.md`](tests/smoke/README.md) for detailed smoke test documentation.
@@ -318,7 +317,7 @@ All documentation must follow the [Documentation Style Guide](docs/style-guide.m
- Add TODO comments for future work
**Markdown Formatting:**
-- Use kebab-case file names (`migration-guide.md`)
+- Use kebab-case file names (e.g., `state-management.md`)
- Always specify language hints in code blocks (```bash, ```go, etc.)
- Use relative links for internal documentation
- Follow heading hierarchy (single H1, proper H2/H3/H4 nesting)
diff --git a/README.md b/README.md
index 7f270df..02cfa3f 100644
--- a/README.md
+++ b/README.md
@@ -8,7 +8,7 @@ Manage JIRA tickets using Markdown files with bidirectional sync. Version contro
[](LICENSE)
[](Dockerfile)
-> **v2.0 Breaking Change:** Legacy `# STORY:` format deprecated. Use `ticketr migrate` to upgrade. See [Migration Guide](docs/migration-guide.md).
+> **Note:** Ticketr requires `# TICKET:` headings. Files using `# STORY:` must be updated before use.
## Features
@@ -100,8 +100,6 @@ ticketr push tickets.md --force-partial-upload
# Discover JIRA schema/fields
ticketr schema > .ticketr.yaml
-# Migrate legacy format
-ticketr migrate old-tickets.md --write
```
## Key Concepts
@@ -218,7 +216,6 @@ See [examples/](examples/) directory for:
- [WORKFLOW.md](docs/WORKFLOW.md) - End-to-end usage guide
- [ARCHITECTURE.md](docs/ARCHITECTURE.md) - Technical architecture
- [TROUBLESHOOTING.md](docs/TROUBLESHOOTING.md) - Common issues
-- [migration-guide.md](docs/migration-guide.md) - v1.x → v2.0 migration
- [state-management.md](docs/state-management.md) - Change detection
- [release-process.md](docs/release-process.md) - Release management
- [CONTRIBUTING.md](CONTRIBUTING.md) - Contribution guide
diff --git a/SUPPORT.md b/SUPPORT.md
index c6fc282..221cb50 100644
--- a/SUPPORT.md
+++ b/SUPPORT.md
@@ -10,7 +10,6 @@ Before seeking support, please check our comprehensive documentation:
- **[Quick Start Guide](https://github.com/karolswdev/ticktr/wiki/Quick-Start-Tutorial)** - Get started in 5 minutes
- **[Documentation](docs/)** - Complete documentation suite
- [WORKFLOW.md](docs/WORKFLOW.md) - End-to-end workflows and examples
- - [Migration Guide](docs/migration-guide.md) - Migrating from legacy format
- [State Management](docs/state-management.md) - Understanding .ticketr.state
- [Release Process](docs/release-process.md) - Version and release information
- **[Examples](examples/)** - Ready-to-use templates and examples
diff --git a/cmd/ticketr/main.go b/cmd/ticketr/main.go
index cbacbf9..1ef9e63 100644
--- a/cmd/ticketr/main.go
+++ b/cmd/ticketr/main.go
@@ -5,7 +5,6 @@ import (
"fmt"
"log"
"os"
- "path/filepath"
"strings"
"github.com/karolswdev/ticktr/internal/adapters/filesystem"
@@ -13,7 +12,6 @@ import (
"github.com/karolswdev/ticktr/internal/core/services"
"github.com/karolswdev/ticktr/internal/core/validation"
"github.com/karolswdev/ticktr/internal/logging"
- "github.com/karolswdev/ticktr/internal/migration"
"github.com/karolswdev/ticktr/internal/state"
"github.com/spf13/cobra"
"github.com/spf13/viper"
@@ -32,9 +30,6 @@ var (
pullOutput string
pullForce bool
- // Migrate command flags
- writeFlag bool
-
rootCmd = &cobra.Command{
Use: "ticketr",
Short: "A tool for managing JIRA tickets as code",
@@ -67,22 +62,6 @@ to overwrite local changes with remote changes when conflicts occur.`,
Run: runSchema,
}
- migrateCmd = &cobra.Command{
- Use: "migrate [file]",
- Short: "Convert legacy # STORY: format to # TICKET:",
- Long: `Migrates Markdown files from deprecated # STORY: schema to canonical # TICKET: schema.
-
-By default, runs in dry-run mode showing preview of changes.
-Use --write flag to apply changes to files.
-
-Examples:
- ticketr migrate path/to/story.md # Preview changes
- ticketr migrate path/to/story.md --write # Apply changes
- ticketr migrate examples/*.md --write # Batch migration`,
- Args: cobra.MinimumNArgs(1),
- Run: runMigrate,
- }
-
// Legacy commands for backward compatibility
legacyCmd = &cobra.Command{
Use: "legacy",
@@ -108,14 +87,10 @@ func init() {
pullCmd.Flags().StringVarP(&pullOutput, "output", "o", "pulled_tickets.md", "output file path")
pullCmd.Flags().BoolVar(&pullForce, "force", false, "Force overwrite local changes with remote changes when conflicts are detected")
- // Migrate command flags
- migrateCmd.Flags().BoolVarP(&writeFlag, "write", "w", false, "Write changes to files")
-
// Add commands to root
rootCmd.AddCommand(pushCmd)
rootCmd.AddCommand(pullCmd)
rootCmd.AddCommand(schemaCmd)
- rootCmd.AddCommand(migrateCmd)
rootCmd.AddCommand(legacyCmd)
// Legacy flags for backward compatibility
@@ -529,100 +504,6 @@ func processFieldForSchema(field map[string]interface{}, customFieldsMap map[str
}
}
-// runMigrate handles the migrate command
-func runMigrate(cmd *cobra.Command, args []string) {
- // Create migrator with DryRun based on writeFlag
- migrator := &migration.Migrator{
- DryRun: !writeFlag,
- }
-
- // Track overall success/failure
- hasErrors := false
- totalFiles := 0
- totalChanges := 0
-
- // Process each file argument (supports glob patterns)
- for _, pattern := range args {
- // Expand glob pattern
- matches, err := filepath.Glob(pattern)
- if err != nil {
- fmt.Printf("Error processing pattern '%s': %v\n", pattern, err)
- hasErrors = true
- continue
- }
-
- if len(matches) == 0 {
- // No glob match, treat as literal file path
- matches = []string{pattern}
- }
-
- // Process each matched file
- for _, filePath := range matches {
- totalFiles++
-
- // Get absolute path for display
- absPath, err := filepath.Abs(filePath)
- if err != nil {
- absPath = filePath
- }
-
- // Perform migration
- content, changed, err := migrator.MigrateFile(filePath)
- if err != nil {
- fmt.Printf("Error migrating %s: %v\n", absPath, err)
- hasErrors = true
- continue
- }
-
- if !changed {
- if verbose {
- fmt.Printf("No changes needed: %s\n", absPath)
- }
- continue
- }
-
- totalChanges++
-
- // If dry-run, show preview
- if migrator.DryRun {
- originalContent, _ := os.ReadFile(filePath)
- preview := migrator.PreviewDiff(absPath, string(originalContent), content)
- fmt.Println(preview)
- } else {
- // Write the migration
- err = migrator.WriteMigration(filePath, content)
- if err != nil {
- fmt.Printf("Error writing %s: %v\n", absPath, err)
- hasErrors = true
- continue
- }
-
- // Count how many replacements were made
- changeCount := strings.Count(content, "# TICKET:") - strings.Count(string(content), "# STORY:")
- if changeCount < 0 {
- changeCount = -changeCount
- }
-
- fmt.Printf("Migrated: %s (%d change(s))\n", absPath, changeCount)
- }
- }
- }
-
- // Print summary
- if totalFiles == 0 {
- fmt.Println("No files matched the provided pattern(s)")
- os.Exit(1)
- }
-
- if verbose {
- fmt.Printf("\nProcessed %d file(s), %d file(s) with changes\n", totalFiles, totalChanges)
- }
-
- if hasErrors {
- os.Exit(1)
- }
-}
-
// runLegacy handles the old command-line interface for backward compatibility
func runLegacy(cmd *cobra.Command, args []string) {
// Check for legacy flags
@@ -773,7 +654,7 @@ func main() {
// Check for legacy usage (no subcommand)
if len(os.Args) > 1 && !strings.HasPrefix(os.Args[1], "-") {
// If first arg is not a flag and not a known command, assume it's a file (legacy)
- knownCommands := []string{"push", "pull", "schema", "migrate", "help", "completion"}
+ knownCommands := []string{"push", "pull", "schema", "help", "completion"}
isKnownCommand := false
for _, cmd := range knownCommands {
if os.Args[1] == cmd {
diff --git a/cmd/ticketr/main_cli_test.go b/cmd/ticketr/main_cli_test.go
index 40bf52c..252f4c0 100644
--- a/cmd/ticketr/main_cli_test.go
+++ b/cmd/ticketr/main_cli_test.go
@@ -135,75 +135,6 @@ func TestPullCmd_Flags(t *testing.T) {
}
}
-// TestMigrateCmd_AcceptsMultipleFiles tests migrate command with multiple file arguments
-func TestMigrateCmd_AcceptsMultipleFiles(t *testing.T) {
- var capturedArgs []string
- testMigrateCmd := &cobra.Command{
- Use: "migrate [file]",
- Args: cobra.MinimumNArgs(1),
- Run: func(cmd *cobra.Command, args []string) {
- capturedArgs = args
- },
- }
-
- testMigrateCmd.SetArgs([]string{"file1.md", "file2.md", "file3.md"})
- err := testMigrateCmd.Execute()
-
- if err != nil {
- t.Fatalf("Expected no error, got: %v", err)
- }
-
- if len(capturedArgs) != 3 {
- t.Errorf("Expected 3 arguments, got %d", len(capturedArgs))
- }
-
- expectedFiles := []string{"file1.md", "file2.md", "file3.md"}
- for i, expected := range expectedFiles {
- if capturedArgs[i] != expected {
- t.Errorf("Expected arg %d to be '%s', got '%s'", i, expected, capturedArgs[i])
- }
- }
-}
-
-// TestMigrateCmd_WriteFlag tests migrate command --write flag
-func TestMigrateCmd_WriteFlag(t *testing.T) {
- var testWrite bool
- testMigrateCmd := &cobra.Command{
- Use: "migrate [file]",
- Args: cobra.MinimumNArgs(1),
- Run: func(cmd *cobra.Command, args []string) {
- testWrite, _ = cmd.Flags().GetBool("write")
- },
- }
-
- testMigrateCmd.Flags().BoolVarP(&testWrite, "write", "w", false, "Write changes")
-
- // Test with --write flag
- testMigrateCmd.SetArgs([]string{"test.md", "--write"})
- err := testMigrateCmd.Execute()
-
- if err != nil {
- t.Fatalf("Expected no error, got: %v", err)
- }
-
- if !testWrite {
- t.Error("Expected write flag to be true")
- }
-
- // Test without --write flag
- testWrite = false
- testMigrateCmd.SetArgs([]string{"test.md"})
- err = testMigrateCmd.Execute()
-
- if err != nil {
- t.Fatalf("Expected no error, got: %v", err)
- }
-
- if testWrite {
- t.Error("Expected write flag to be false")
- }
-}
-
// TestConfigFile_Override tests that --config flag overrides default config location
func TestConfigFile_Override(t *testing.T) {
var testCfgFile string
@@ -378,13 +309,6 @@ func TestCommandHelp(t *testing.T) {
Short: "Pull tickets from JIRA",
},
},
- {
- name: "migrate",
- command: &cobra.Command{
- Use: "migrate [file]",
- Short: "Migrate legacy format",
- },
- },
{
name: "schema",
command: &cobra.Command{
diff --git a/docs/ARCHITECTURE.md b/docs/ARCHITECTURE.md
index d5d86b8..69d67c5 100644
--- a/docs/ARCHITECTURE.md
+++ b/docs/ARCHITECTURE.md
@@ -149,12 +149,8 @@ ticketr/
│ │ ├── rotation.go # Log rotation
│ │ └── redaction.go # Sensitive data filtering
│ │
-│ └── migration/ # Format migration
-│ ├── migrator.go # STORY → TICKET conversion
-│ └── migrator_test.go
-│
├── testdata/ # Test fixtures
-│ ├── legacy_story/ # Legacy format samples
+│ ├── unsupported_story/ # Fixtures that trigger STORY heading errors
│ ├── valid_tickets/ # Valid test cases
│ └── invalid_tickets/ # Invalid test cases
│
@@ -174,7 +170,6 @@ ticketr/
│ ├── WORKFLOW.md # End-to-end workflow guide
│ ├── ci.md # CI/CD pipeline
│ ├── state-management.md # State tracking details
-│ ├── migration-guide.md # v1 → v2 migration
│ ├── integration-testing-guide.md # Integration test scenarios
│ ├── qa-checklist.md # Quality assurance guide
│ ├── legacy/ # Deprecated documentation
@@ -332,7 +327,7 @@ field_mappings:
4. Custom fields extraction from `## Fields` sections
**Key Features:**
-- Rejects legacy `# STORY:` format with helpful errors
+- Rejects `# STORY:` headings with helpful errors
- Supports multi-ticket files
- Handles nested tasks with inheritance
@@ -375,17 +370,6 @@ Conflict = Local changed AND Remote changed
- Errors and warnings
- Timestamps for all operations
-#### Migration Engine (`internal/migration/`)
-
-**Purpose:** Convert legacy `# STORY:` format to canonical `# TICKET:` format
-
-**Operations:**
-- Dry-run mode (preview changes)
-- Write mode (apply changes)
-- Batch processing support
-
----
-
## Data Flow
### Push Operation
@@ -479,7 +463,6 @@ User: ticketr pull --project PROJ --output tickets.md
**Solution:** Generic `Ticket` struct with `CustomFields map[string]string` supporting any Jira field.
-**Migration:** `ticketr migrate` command converts legacy `# STORY:` to `# TICKET:`.
### 2. Deterministic Hashing (Milestone 4)
diff --git a/docs/README.md b/docs/README.md
index 89f846b..41e2e2f 100644
--- a/docs/README.md
+++ b/docs/README.md
@@ -1,21 +1,20 @@
# Ticketr Documentation
-## Test Fixtures and Legacy Samples
+## Test Fixtures and Unsupported Samples
-### Legacy Story Schema (`testdata/legacy_story/`)
+### Unsupported Story Schema (`testdata/unsupported_story/`)
-This directory contains markdown files using the deprecated `# STORY:` schema format. These samples serve a specific purpose:
+This directory contains markdown files using the old `# STORY:` heading. These samples serve a specific purpose:
-**Purpose:** Regression testing to ensure the parser correctly rejects legacy format with helpful error messages.
+**Purpose:** Regression testing to ensure the parser correctly rejects unsupported headings with helpful error messages.
**Important Notes:**
- These files are **NOT** valid for current Ticketr operations
-- They exist solely for backward compatibility testing
+- They exist solely for regression testing
- The canonical schema is `# TICKET:` (see development/REQUIREMENTS.md PROD-201)
-- Users encountering `# STORY:` format should migrate to `# TICKET:` immediately
+- Users encountering `# STORY:` headings should rename them to `# TICKET:` manually before using Ticketr
**Related Files:**
-- Migration guidance: README.md "Migrating from v1.x" section
- Schema specification: development/REQUIREMENTS.md (PROD-201)
- Parser rejection tests: `internal/parser/parser_test.go`
diff --git a/docs/TROUBLESHOOTING.md b/docs/TROUBLESHOOTING.md
index b5ed14b..1e8dba5 100644
--- a/docs/TROUBLESHOOTING.md
+++ b/docs/TROUBLESHOOTING.md
@@ -342,27 +342,19 @@ ticketr pull --project PROJ -o tickets.md # Re-initialize
## Validation Errors
-### Legacy Format Error
+### Unsupported Story Heading
-**Problem:** `Error: Legacy '# STORY:' format detected`
+**Problem:** `Error: '# STORY:' format detected`
-**Solution:**
-
-```bash
-# Migrate to new format
-ticketr migrate old-file.md # Preview
-ticketr migrate old-file.md --write # Apply
+**Solution:** Update the heading manually:
-# Batch migration
-ticketr migrate tickets/*.md --write
-```
-
-**Manual migration:**
```markdown
-# STORY: Old Format # ❌ Old
-# TICKET: New Format # ✅ New
+# STORY: Old Format # ❌ Unsupported
+# TICKET: New Format # ✅ Supported
```
+The parser intentionally blocks `# STORY:` so the fix is to rename the heading before running Ticketr again.
+
### Hierarchical Validation Error
**Problem:** `A 'Story' cannot be the child of an 'Epic'`
@@ -580,7 +572,7 @@ echo $JIRA_EMAIL
echo $JIRA_PROJECT_KEY
# 4. Verify file syntax
-ticketr migrate tickets.md # Preview without --write
+grep -n "#\s*STORY:" tickets.md # Ensure unsupported headings are updated
# 5. Test with verbose
ticketr push tickets.md --verbose
@@ -613,7 +605,6 @@ If you're still stuck:
1. **Check Documentation:**
- [WORKFLOW.md](WORKFLOW.md) - Complete usage guide
- - [Migration Guide](migration-guide.md) - Legacy format migration
- [State Management](state-management.md) - Understanding .ticketr.state
- [FAQ](https://github.com/karolswdev/ticktr/wiki/FAQ)
diff --git a/docs/WORKFLOW.md b/docs/WORKFLOW.md
index 9aa7cd4..c379609 100644
--- a/docs/WORKFLOW.md
+++ b/docs/WORKFLOW.md
@@ -241,18 +241,9 @@ Tickets updated: 1
Processing complete!
```
-#### Scenario B: Migration from Legacy Format
+#### Scenario B: Updating Older Files
-If you have old `# STORY:` files:
-```bash
-# Preview changes
-$ ticketr migrate legacy-stories.md
-
-# Apply migration
-$ ticketr migrate legacy-stories.md --write
-
-Migrated: /path/to/legacy-stories.md (5 change(s))
-```
+If you encounter an older Markdown file that still uses `# STORY:` headings, rename them to `# TICKET:` before running Ticketr. The parser will otherwise stop with an error so no unintended changes occur.
## Key Concepts
@@ -319,5 +310,4 @@ Migrated: /path/to/legacy-stories.md (5 change(s))
## Next Steps
- Read [State Management Guide](state-management.md) for details on hashing
-- Read [Migration Guide](migration-guide.md) to migrate legacy # STORY: files
- Read [Integration Testing Guide](integration-testing-guide.md) for testing
diff --git a/docs/ci.md b/docs/ci.md
index f80ae4f..9437c64 100644
--- a/docs/ci.md
+++ b/docs/ci.md
@@ -399,7 +399,7 @@ go mod tidy
**Example failure log:**
```
--- FAIL: TestParser_RejectsLegacyStoryFormat (0.00s)
- parser_test.go:113: Expected error message to contain 'Legacy', got: legacy '# STORY:' format detected
+ parser_test.go:113: Expected error message to mention 'TICKET', got: '# STORY:' format detected at line 1 - ticketr requires '# TICKET:' headings.
FAIL
FAIL github.com/karolswdev/ticktr/internal/parser 0.123s
```
diff --git a/docs/cleanup-assessment.md b/docs/cleanup-assessment.md
index a24c832..a4ce7a1 100644
--- a/docs/cleanup-assessment.md
+++ b/docs/cleanup-assessment.md
@@ -56,23 +56,6 @@
---
-### docs/migration-guide.md
-
-**Reason:** Essential guide for users migrating from legacy `# STORY:` format to canonical `# TICKET:` format. Actively referenced in README.md and error messages. Provides both automated and manual migration paths.
-
-**Quality:** Excellent
-- Clear rationale for migration
-- Step-by-step instructions (automated and manual)
-- Migration checklist
-- Common scenarios covered
-- Troubleshooting section
-- References to requirements (PROD-201)
-- Rollback strategy included
-
-**Recommendation:** Keep as-is. Critical user-facing documentation.
-
----
-
### docs/qa-checklist.md
**Reason:** Comprehensive quality assurance guide with pre-commit, pre-PR, and pre-release checklists. Actively referenced in CONTRIBUTING.md and ci.md. Essential for maintaining code quality standards.
@@ -91,12 +74,12 @@
### docs/README.md
-**Reason:** Provides context for legacy test fixtures in testdata/legacy_story/. Explains deprecation and migration path. Short and focused.
+**Reason:** Provides context for the unsupported story fixtures in `testdata/unsupported_story/`. Explains why the parser rejects `# STORY:` headings and where to find related tests. Short and focused.
**Quality:** Good
- Clear purpose statement
-- Explains legacy format testing
-- References migration guidance
+- Explains unsupported format testing
+- References parser guidance
- Links to related files
**Recommendation:** Keep as-is. May be expanded in future milestones as noted.
@@ -126,7 +109,7 @@
**Quality:** Excellent
- Step-by-step workflow with actual commands
- Demonstrates all major features (push, pull, state, inheritance, conflicts)
-- Includes advanced scenarios (partial upload, migration)
+- Includes advanced scenarios (partial upload, manual remediation)
- Key concepts explained (state, inheritance, conflicts, logging)
- Common workflows section
- Troubleshooting tips
@@ -140,7 +123,7 @@
**None identified.**
-All documentation assessed is current, accurate, and actively supports the v2.0 feature set. No documents describe deprecated features requiring archival.
+All documentation assessed is current, accurate, and actively supports the 1.0 feature set. No documents describe deprecated features requiring archival.
---
@@ -164,14 +147,13 @@ No duplicates, empty files, or outdated-with-no-historical-value documents found
### 2. Documentation Completeness
-**Observation:** The 8 files in docs/ provide comprehensive coverage of:
+**Observation:** The 7 key files in docs/ provide comprehensive coverage of:
- CI/CD pipeline (ci.md)
- Integration testing (integration-testing-guide.md, integration-test-results-milestone-7.md)
-- Migration (migration-guide.md)
- Quality assurance (qa-checklist.md)
- State management (state-management.md)
- Workflows (WORKFLOW.md)
-- Legacy fixtures context (README.md)
+- Unsupported fixture context (README.md)
**Action:** No gaps identified. Documentation set is complete for current feature set.
@@ -211,7 +193,6 @@ No duplicates, empty files, or outdated-with-no-historical-value documents found
- ci.md
- integration-testing-guide.md
- integration-test-results-milestone-7.md
-- migration-guide.md
- qa-checklist.md
- README.md
- state-management.md
diff --git a/docs/development/README.md b/docs/development/README.md
index cacc9ca..f564e74 100644
--- a/docs/development/README.md
+++ b/docs/development/README.md
@@ -5,7 +5,7 @@ This directory contains internal development and planning artifacts for Ticketr
## Contents
### [REQUIREMENTS.md](REQUIREMENTS.md)
-**Purpose:** Comprehensive requirements specification for Ticketr v2.0+
+**Purpose:** Comprehensive requirements specification for Ticketr 1.0
**Key Sections:**
- PROD-xxx requirement IDs and specifications
diff --git a/docs/development/REQUIREMENTS.md b/docs/development/REQUIREMENTS.md
index b21f51b..92ceaa3 100644
--- a/docs/development/REQUIREMENTS.md
+++ b/docs/development/REQUIREMENTS.md
@@ -1,11 +1,11 @@
# Ticketr - Software Requirements Specification
-**Version:** 2.0
-**Status:** Modernization Baseline
+**Version:** 1.0
+**Status:** Release Baseline
## Introduction
-This document outlines the software requirements for **Ticketr v2.0**. It serves as the single source of truth for what the system must do, the constraints under which it must operate, and the rules governing its development and deployment.
+This document outlines the software requirements for **Ticketr 1.0**. It serves as the single source of truth for what the system must do, the constraints under which it must operate, and the rules governing its development and deployment.
Each requirement has a **unique, stable ID** (e.g., `PROD-001`). These IDs **MUST** be used to link implementation stories and test cases back to these foundational requirements, ensuring complete traceability.
@@ -26,26 +26,22 @@ The requirement keywords (`MUST`, `MUST NOT`, `SHOULD`, `SHOULD NOT`, `MAY`) are
| **PROD-005** | Rich Task Definitions | The system **MUST** be able to parse and sync a `Description` and `Acceptance Criteria` for individual tasks, in addition to their titles. Tasks **MUST** support custom `## Fields` sections for field overrides. **Status:** ✅ COMPLETE (Milestone 8 - Pull support added). **Traceability:** Push: `ticket_service.go:109-114`; Pull: `jira_adapter.go:824-907` (parseJiraSubtask); Tests: TC-701.x (push), TC-208.x (pull) | To allow for the creation of detailed, well-defined tasks that do not require immediate follow-up in the Jira UI. |
| **PROD-009** | Hierarchical Field Inheritance | The system **MUST** implement field inheritance where child tasks inherit custom fields from their parent ticket, with task-specific fields overriding inherited values. **Status:** ✅ COMPLETE (Milestone 7). **Traceability:** Implementation in `ticket_service.go:39-53,109-114`; Tests: TC-701.1, TC-701.2, TC-701.3, TC-701.4 | To enable consistent field management while allowing task-specific customizations. |
| **PROD-010** | Query-Based Pull Synchronization | The system **MUST** support pulling tickets from Jira based on project, epic, or custom JQL queries, converting them to the canonical Markdown format. **Status:** ✅ COMPLETE (Milestone 8). **Traceability:** Implementation in `jira_adapter.go:727-736,741-822,824-907`; Tests: TC-208.1, TC-208.2, TC-208.3, TC-208.4 | To enable bidirectional synchronization and maintain Markdown as the source of truth. |
-| **PROD-201** | Generic `TICKET` Markdown Schema | The system **MUST** recognize and parse `# TICKET:` blocks with structured `## Description`, `## Fields`, `## Acceptance Criteria`, and `## Tasks` sections. See subsection below for legacy deprecation details. | To support any Jira issue type and custom field configuration. |
+| **PROD-201** | Generic `TICKET` Markdown Schema | The system **MUST** recognize and parse `# TICKET:` blocks with structured `## Description`, `## Fields`, `## Acceptance Criteria`, and `## Tasks` sections. Files using `# STORY:` **MUST** be rejected with a clear error referencing the supported heading. | To support any Jira issue type and custom field configuration. |
| **PROD-202** | Hierarchical Field Inheritance Logic | The system **MUST** calculate final fields for tasks by merging task-specific fields over parent ticket fields. **Status:** ✅ COMPLETE (Milestone 7). **Traceability:** Implementation in `ticket_service.go:39-53` (calculateFinalFields); Tests: TC-701.1, TC-701.2, TC-701.3, TC-701.4 | To ensure consistent field inheritance while allowing task-level overrides. |
| **PROD-203** | Dynamic Field Mapping | The system **MUST** support configurable field mappings between human-readable names and JIRA field IDs, with automatic type conversion for number and array fields. | To support different JIRA configurations and custom fields across instances. |
| **PROD-204** | State-Based Change Detection | The system **MUST** track content hashes of tickets to skip unchanged items during push operations. **Status:** ✅ COMPLETE (Milestone 9). **Traceability:** Implementation in `push_service.go:50,67-70,161`; StateManager in `main.go:218`; Tests: TestPushService_SkipsUnchangedTickets | To minimize API calls and improve performance for large ticket sets. |
| **PROD-205** | Query-Based Ticket Pulling | The system **MUST** construct JQL queries combining project filters with user-provided JQL for flexible ticket retrieval. | To enable targeted synchronization of specific ticket subsets. |
| **PROD-206** | Markdown Rendering | The system **MUST** convert JIRA tickets to well-formed Markdown documents preserving all field mappings and hierarchy. | To maintain bidirectional format consistency. |
-### PROD-201: Legacy `# STORY:` Schema Deprecation
+### PROD-201: `# STORY:` Heading Rejection
-**Rationale:** The generic `# TICKET:` schema supports multiple issue types (stories, bugs, tasks, epics) while maintaining backward compatibility with hierarchical validation. The legacy `# STORY:` format was overly specific and did not align with Jira's flexible issue type system.
+**Rationale:** Early prototypes used a `# STORY:` heading, but the final 1.0 format needed to support any Jira issue type. Enforcing `# TICKET:` keeps the schema consistent across stories, tasks, bugs, and epics.
-**Migration Path:**
-- **Manual (Current):** Use find-replace to change `# STORY:` → `# TICKET:` in all `.md` files
-- **Automated (Milestone 1):** The `ticketr migrate` command will handle batch conversions
-- **Parser Behavior:** v2.0+ parsers reject `# STORY:` format with clear error messages
+**Guidance:** If older files still use `# STORY:`, rename the heading to `# TICKET:` manually before running Ticketr.
-**Test Coverage:** Legacy samples in `testdata/legacy_story/` ensure regression detection. These samples are intentionally invalid and used solely to verify the parser correctly rejects deprecated formats with helpful user guidance.
+**Test Coverage:** Fixtures in `testdata/unsupported_story/` ensure the parser continues to reject `# STORY:` headings with a helpful error message.
**Cross-References:**
-- Migration guidance: README.md "Migrating from v1.x" section
- Test fixture documentation: docs/README.md
- Parser rejection tests: `internal/parser/parser_test.go`
@@ -104,4 +100,4 @@ The requirement keywords (`MUST`, `MUST NOT`, `SHOULD`, `SHOULD NOT`, `MAY`) are
| ID | Title | Description | Rationale |
| :--- | :--- | :--- | :--- |
-| **DEV-001** | **Containerized Execution** | The application **MUST** be distributed and executed as a Docker container. | To ensure a consistent, portable, and isolated execution environment, abstracting away the host machine's configuration. |
\ No newline at end of file
+| **DEV-001** | **Containerized Execution** | The application **MUST** be distributed and executed as a Docker container. | To ensure a consistent, portable, and isolated execution environment, abstracting away the host machine's configuration. |
diff --git a/docs/development/ROADMAP.md b/docs/development/ROADMAP.md
index a368a89..4d9b6bf 100644
--- a/docs/development/ROADMAP.md
+++ b/docs/development/ROADMAP.md
@@ -13,7 +13,7 @@ This roadmap captures the opinionated engineering plan to close the usability ga
## Key References & Background
-- Product requirements: `REQUIREMENTS-v2.md`
+- Product requirements: `docs/development/REQUIREMENTS.md`
- CLI entrypoint: `cmd/ticketr/main.go`
- Parser and writer: `internal/parser/parser.go`, `internal/adapters/filesystem/file_repository.go`
- Push/Pull services: `internal/core/services/*`
@@ -23,7 +23,7 @@ This roadmap captures the opinionated engineering plan to close the usability ga
## Execution Preparation
-1. Read `REQUIREMENTS-v2.md` to confirm acceptance targets (e.g., PROD-004 logging, PROD-009 inheritance).
+1. Read `docs/development/REQUIREMENTS.md` to confirm acceptance targets (e.g., PROD-004 logging, PROD-009 inheritance).
2. Run `go test ./...` to capture current baseline (expect failures if environment prerequisites are missing).
3. Note any uncommitted local changes so you do not overwrite them.
4. Set `JIRA_*` environment variables or prepare mocks before touching Jira integrations.
@@ -37,15 +37,15 @@ Goal: Ensure contributors understand canonical formats before modifying behaviou
**Status:** COMPLETE (Commit: ecc24d4)
**Completed:** 2025-10-16
-- [x] Confirm `# TICKET:` is the canonical Markdown heading and that legacy `# STORY:` content will be rejected with a clear error. (`internal/parser/parser.go`)
-- [x] Document the deprecation path and rationale in `README.md` and `REQUIREMENTS-v2.md`, including migration guidance.
-- [x] Capture sample legacy files under `testdata/legacy_story/*.md` for regression tests.
+- [x] Confirm `# TICKET:` is the canonical Markdown heading and ensure `# STORY:` content is rejected with a clear error. (`internal/parser/parser.go`)
+- [x] Document the supported Markdown schema in `README.md` and `docs/development/REQUIREMENTS.md`, including guidance for unsupported headings.
+- [x] Capture sample fixtures under `testdata/unsupported_story/*.md` for regression tests.
- [x] Update/extend automated tests affected by this milestone and run `go test ./...`.
-- [x] Update documentation: refresh `README.md` overview to declare the canonical `# TICKET:` format and point migration notes to `REQUIREMENTS-v2.md`; ensure `REQUIREMENTS-v2.md` references legacy deprecation; add a short note to `docs/README.md` (create if missing) describing the legacy samples in `testdata/legacy_story/`.
+- [x] Update documentation: refresh `README.md` overview to declare the canonical `# TICKET:` format; ensure `docs/development/REQUIREMENTS.md` records the rejection policy; add a short note to `docs/README.md` describing the unsupported samples in `testdata/unsupported_story/`.
**Deliverables:**
-- README.md: Updated with TICKET format and migration guidance
-- REQUIREMENTS-v2.md: Enhanced PROD-201 with deprecation subsection
+- README.md: Updated with TICKET format guidance
+- docs/development/REQUIREMENTS.md: Enhanced PROD-201 with unsupported heading guidance
- docs/README.md: Created documenting test fixture strategy
- All user-facing examples use canonical # TICKET: format
@@ -53,26 +53,25 @@ Goal: Ensure contributors understand canonical formats before modifying behaviou
## Milestone 1 – Canonical Markdown Schema & Tooling ✅
-Goal: Align documentation, templates, and tooling with the canonical schema; provide migration support.
+Goal: Align documentation, templates, and tooling with the canonical schema; provide clear guidance for unsupported headings.
**Status:** COMPLETE (Commits: 3a49e78, 943fbfa)
**Completed:** 2025-10-16
**Test Results:** 36 passed, 0 failed, 3 skipped (JIRA integration)
- [x] Update all examples, templates, and README snippets to use the `# TICKET:` schema. (`README.md`, `examples/*.md`)
-- [x] Add a parser error explaining how to migrate when a legacy heading is detected. (`internal/parser/parser.go`)
-- [x] Introduce a `ticketr migrate ` helper (optional but recommended) that rewrites legacy `# STORY:` blocks to `# TICKET:` while preserving content. (`cmd/ticketr/main.go`, new helper file)
-- [x] Extend parser unit tests to cover canonical parsing and rejection/migration paths. (`internal/parser/parser_test.go`)
+- [x] Add a parser error explaining how to update when a `# STORY:` heading is detected. (`internal/parser/parser.go`)
+- [x] Document a manual update path for `# STORY:` files and drop the unused `ticketr migrate` prototype before release.
+- [x] Extend parser unit tests to cover canonical parsing and rejection guidance. (`internal/parser/parser_test.go`)
- [x] Update/extend automated tests affected by this milestone and run `go test ./...`.
-- [x] Update documentation: rewrite README quick-start and advanced sections to the new schema; add `docs/migration-guide.md` covering legacy `# STORY` conversion; update `examples/README.md` (create) to describe templates.
+- [x] Update documentation: rewrite README quick-start and advanced sections to the new schema; ensure `docs/development/REQUIREMENTS.md` covers `# TICKET:` usage; update `examples/README.md` (create) to describe templates.
**Deliverables:**
-- Parser rejection: Legacy # STORY: format rejected with actionable error (line number + migration command)
-- Migration command: ticketr migrate with dry-run (default) and --write modes
-- Test coverage: 11 new tests (3 parser + 7 migration + 1 service)
-- Documentation: docs/migration-guide.md (175 lines), examples/README.md (155 lines)
+- Parser rejection: `# STORY:` heading rejected with actionable error (includes line number and fix instructions)
+- Test coverage: 4 new tests (parser rejection cases + service guardrail)
+- Documentation: examples/README.md (155 lines) with schema reminders
- Examples: All 3 templates migrated to canonical format
-- README: Enhanced migration section with quick commands and cross-references
+- README: Enhanced schema section with quick commands and cross-references
**Known Issues:**
- Minor: Migration guide references non-existent `ticketr validate` command (non-blocking)
@@ -239,9 +238,9 @@ Goal: Ensure tasks inherit parent fields with local overrides before hitting Jir
- [x] Use `calculateFinalFields` (or successor) to merge parent `CustomFields` into each task before calling the Jira adapter. (`internal/core/services/ticket_service.go`, `internal/core/services/push_service.go`)
- [x] Update Jira adapter methods to accept merged fields and map them to correct Jira payload fields. (`internal/adapters/jira/jira_adapter.go`)
- [x] Add unit tests verifying that tasks inherit parent values unless overridden. (`internal/core/services/ticket_service_test.go`)
-- [x] Update documentation to describe field inheritance rules. (`README.md`, `REQUIREMENTS-v2.md`)
+- [x] Update documentation to describe field inheritance rules. (`README.md`, `docs/development/REQUIREMENTS.md`)
- [x] Update/extend automated tests affected by this milestone and run `go test ./...`.
-- [x] Update documentation: detail field inheritance rules in `README.md` and align `REQUIREMENTS-v2.md` acceptance text; create `docs/field-inheritance.md` summarising examples if not already present.
+- [x] Update documentation: detail field inheritance rules in `README.md` and align `docs/development/REQUIREMENTS.md` acceptance text; create `docs/field-inheritance.md` summarising examples if not already present.
- [x] Integration test with real JIRA instance to validate field inheritance end-to-end.
**Deliverables:**
@@ -306,7 +305,7 @@ Dependencies: Milestone 7 (shared understanding of task fields).
## Milestone 9 – State-Aware Push Integration ✅
-Goal: Replace the legacy push flow with the stateful service that honours PROD-204.
+Goal: Replace the original push flow with the stateful service that honours PROD-204.
**Status:** COMPLETE
**Completed:** 2025-10-16
@@ -325,7 +324,7 @@ Goal: Replace the legacy push flow with the stateful service that honours PROD-2
- Field inheritance: calculateFinalFields() added to PushService (push_service.go:27-41)
- Task processing: Field inheritance applied before JIRA operations (push_service.go:89-94)
- State-based skipping: Unchanged tickets skipped to minimize API calls (push_service.go:67-70)
-- TicketService deprecated: Clear comment marking legacy status (ticket_service.go:12-13)
+- TicketService deprecated: Clear comment marking archived implementation status (ticket_service.go:12-13)
- Test coverage: 2 new field inheritance tests (TestPushService_FieldInheritance_*)
- Force-partial-upload: Already working, no changes needed (verified by tests)
@@ -349,8 +348,8 @@ Goal: Capture the new behaviours and ensure contributors/users understand them.
**Completed:** 2025-10-16
**Documentation:** docs/WORKFLOW.md, CONTRIBUTING.md, README.md Quick Reference
-- [x] Refresh the README with updated command usage, logging, conflict resolution, state handling, and migration info. (`README.md`)
-- [x] Update requirement traceability to show compliance with PROD/NFR/DEV items. (`REQUIREMENTS-v2.md`)
+- [x] Refresh the README with updated command usage, logging, conflict resolution, state handling, and schema guidance. (`README.md`)
+- [x] Update requirement traceability to show compliance with PROD/NFR/DEV items. (`docs/development/REQUIREMENTS.md`)
- [x] Provide an end-to-end walkthrough (e.g., sample Markdown → push → pull → log review). (`README.md` or new `docs/WORKFLOW.md`)
- [x] Add CONTRIBUTING notes about testing expectations and logging artefacts.
- [x] Update/extend automated tests affected by this milestone and run `go test ./...`.
@@ -360,7 +359,7 @@ Goal: Capture the new behaviours and ensure contributors/users understand them.
- docs/WORKFLOW.md: Complete end-to-end walkthrough (379 lines)
- CONTRIBUTING.md: Testing, architecture, PR guidelines (211 lines)
- README.md: Quick Reference section (lines 52-90)
-- REQUIREMENTS-v2.md: PROD-204 traceability updated (line 32)
+- docs/development/REQUIREMENTS.md: PROD-204 traceability updated (line 32)
- Test baseline maintained: 69 tests (66 passed, 3 skipped)
**Implementation Notes:**
@@ -384,7 +383,7 @@ Goal: Lock down regressions via automated checks.
**Coverage:** 52.5% (up from 45.2%)
- [x] Expand unit/integration test coverage to include new features. (`internal/...`)
-- [x] Add smoke tests for CLI flows (e.g., scripts under `evidence/` or new `integration/` directory).
+- [x] Add smoke tests for CLI flows (now tracked under `tests/smoke/`).
- [x] Integrate `go vet`, `staticcheck`, and formatting checks into CI (GitHub Actions or local script). (`.github/workflows/*.yml` or new pipeline)
- [x] Document a verification checklist (commands to run, expected outputs) in `HANDOFF-BEFORE-PHASE-3.md` or a new QA doc.
- [x] Update/extend automated tests affected by this milestone and run `go test ./...`.
@@ -393,7 +392,7 @@ Goal: Lock down regressions via automated checks.
**Deliverables:**
- CI/CD pipeline: .github/workflows/ci.yml with 5 jobs (build, test, coverage, lint, smoke-tests)
- Test coverage: 45.2% → 52.5% (+27 new tests across filesystem, JIRA, and CLI layers)
-- Smoke test suite: tests/smoke/ with 7 scenarios (migration, push, pull, state, logs, help, concurrent)
+- Smoke test suite: tests/smoke/ with 6 scenarios (push, pull, state, logs, help, concurrent)
- Quality automation: scripts/quality.sh with 7 automated checks
- Documentation: docs/qa-checklist.md (468 lines), docs/ci.md (691 lines)
- OS matrix: Ubuntu, macOS; Go versions: 1.21, 1.22, 1.23
@@ -404,7 +403,7 @@ Dependencies: Milestones 1–10.
## Milestone 12 – Requirements Consolidation & Documentation Governance ✅
-Goal: Base the product exclusively on the v2 specification and publish an authoritative documentation set.
+Goal: Base the product exclusively on the 1.0 specification and publish an authoritative documentation set.
**Status:** COMPLETE
**Completed:** 2025-10-16
@@ -412,22 +411,22 @@ Goal: Base the product exclusively on the v2 specification and publish an author
**Coverage:** 52.5% maintained
**Documentation:** ARCHITECTURE.md, docs/style-guide.md, docs/cleanup-assessment.md
-- [x] Deprecate `REQUIREMENTS.md` (v1) by archiving it under `docs/legacy/` and updating `REQUIREMENTS-v2.md` with any missing requirements or clarifications.
-- [x] Rewrite README examples and workflows to use the canonical `# TICKET` schema, replacing all legacy `# STORY` snippets. (Verification: All examples already canonical)
+- [x] Deprecate the early requirements draft by archiving it under `docs/legacy/` and updating `docs/development/REQUIREMENTS.md` with any missing clarifications.
+- [x] Rewrite README examples and workflows to use the canonical `# TICKET` schema, replacing all pre-release `# STORY` snippets. (Verification: All examples already canonical)
- [x] Scrutinize the `docs` directory, per file - determine its applicability, determine if it's an intermediate artifact, adding your assessment into docs/cleanup-assessment.md
- [x] Apply the assessment, remove any non-essential, transitive documents. Leave behind stellar documentation instead. (Result: All 8 files kept - all high quality)
-- [x] Update `examples/*.md` to the new schema or move them under an archived legacy folder with clear warnings. (Verification: All examples already canonical)
-- [x] Retire phase playbooks (`PHASE-1.md`, `PHASE-2.md`, `PHASE-3.md`, `phase-hardening.md`, `PHASE-n.md`) by moving them to `docs/history/` with a README explaining their legacy status.
+- [x] Update `examples/*.md` to the new schema or move them under an archived folder with clear warnings. (Verification: All examples already canonical)
+- [x] Retire phase playbooks (`PHASE-1.md`, `PHASE-2.md`, `PHASE-3.md`, `phase-hardening.md`, `PHASE-n.md`) by moving them to `docs/history/` with a README explaining their historical status.
- [x] Refresh `HANDOFF-BEFORE-PHASE-3.md` to reflect the current architecture or replace it with an up-to-date engineering overview. (Result: Replaced with comprehensive ARCHITECTURE.md)
- [x] Add a docs style guide / contribution rules covering tone, code fences, anchors, and file naming, referenced from `CONTRIBUTING.md`.
- [x] Update/extend automated tests affected by this milestone and run `go test ./...`. (Result: 103/103 passing, 52.5% coverage maintained)
-- [x] Update documentation: move v1 docs to `docs/legacy/` with a README explaining scope, update `REQUIREMENTS-v2.md` cross-links, formalise `docs/style-guide.md`, and expand `CONTRIBUTING.md` with documentation governance.
+- [x] Update documentation: move earlier docs to `docs/legacy/` with a README explaining scope, update `docs/development/REQUIREMENTS.md` cross-links, formalise `docs/style-guide.md`, and expand `CONTRIBUTING.md` with documentation governance.
**Deliverables:**
- ARCHITECTURE.md: Comprehensive system architecture overview (766 lines)
- docs/style-guide.md: Documentation standards and best practices (807 lines)
- docs/cleanup-assessment.md: Detailed assessment of all documentation files
-- docs/legacy/README.md: Legacy v1 requirements archived with explanatory context
+- docs/legacy/README.md: Archived v1 requirements with explanatory context
- docs/history/README.md: Phase playbooks archived with historical context
- CONTRIBUTING.md: Updated with style guide references and documentation governance
diff --git a/docs/history/README.md b/docs/history/README.md
index 914e9ed..2bdf644 100644
--- a/docs/history/README.md
+++ b/docs/history/README.md
@@ -63,7 +63,7 @@ These historical playbooks are kept for:
**DO NOT** use these playbooks for current development:
- They describe work already completed
-- Current requirements are in REQUIREMENTS-v2.md
+- Current requirements are in docs/development/REQUIREMENTS.md
- Current roadmap is in ROADMAP.md
- Current architecture is in ARCHITECTURE.md
@@ -85,7 +85,7 @@ These historical playbooks are kept for:
## Related Documentation
-- [REQUIREMENTS-v2.md](/REQUIREMENTS-v2.md) - Current requirements specification
+- [docs/development/REQUIREMENTS.md](/docs/development/REQUIREMENTS.md) - Current requirements specification
- [docs/legacy/REQUIREMENTS-v1.md](/docs/legacy/REQUIREMENTS-v1.md) - Original v1 requirements (deprecated)
- [docs/integration-test-results-milestone-7.md](/docs/integration-test-results-milestone-7.md) - Example milestone completion evidence
diff --git a/docs/history/phase-hardening.md b/docs/history/phase-hardening.md
index cc84d38..e23dea9 100644
--- a/docs/history/phase-hardening.md
+++ b/docs/history/phase-hardening.md
@@ -21,7 +21,7 @@ You are an expert, test-driven software development agent executing a developmen
| :--- | :--- |
| PHASE-3 | The Hardening |
-> **As a** Lead Systems Engineer, **I want** to finalize the Ticketr v2.0 feature set by integrating robust validation, conflict management, and comprehensive reporting, **so that** the tool is reliable, safe, and ready for enterprise-wide adoption as the definitive "Tickets-as-Code" engine.
+> **As a** Lead Systems Engineer, **I want** to finalize the Ticketr 1.0 feature set by integrating robust validation, conflict management, and comprehensive reporting, **so that** the tool is reliable, safe, and ready for enterprise-wide adoption as the definitive "Tickets-as-Code" engine.
---
@@ -29,13 +29,13 @@ You are an expert, test-driven software development agent executing a developmen
This section is a reference library defining the acceptance criteria for this phase.
-* **Requirement:** **`PROD-201`** - **Generic `TICKET` Markdown Schema** ([Link](./REQUIREMENTS-v2.md#PROD-201))
+* **Requirement:** **`PROD-201`** - **Generic `TICKET` Markdown Schema** ([Link](../development/REQUIREMENTS.md#prod-201))
* **Test Case ID:** `TC-301.1`
* **Test Method Signature:** `func TestTicketService_RejectsLegacyStoryFormat(t *testing.T)`
* **Test Logic:** (Arrange) Create a Markdown file containing the old `# STORY:` format. (Act) Pass this file to the `ticket_service`. (Assert) The service returns an error and the `ProcessResult` indicates zero tickets were processed.
* **Required Proof of Passing:** Console output from `go test` showing the `TestTicketService_RejectsLegacyStoryFormat` test passing.
-* **Requirement:** **`PROD-002`** - **Hierarchical Validation** ([Link](./REQUIREMENTS-v2.md#PROD-002))
+* **Requirement:** **`PROD-002`** - **Hierarchical Validation** ([Link](../development/REQUIREMENTS.md#prod-002))
* **Test Case ID:** `TC-302.1`
* **Test Method Signature:** `func TestPushCommand_FailsFastOnValidationError(t *testing.T)`
* **Test Logic:** (Arrange) Create a Markdown file with a known validation error (e.g., a "Sub-task" under an "Epic"). Mock the `JiraAdapter` to fail the test if any of its `Create/Update` methods are called. (Act) Execute the `push` command logic. (Assert) The command exits with a non-zero status code, prints the validation error, and the mock confirms that no API calls were made.
@@ -47,7 +47,7 @@ This section is a reference library defining the acceptance criteria for this ph
* **Test Logic:** (Arrange) Create a `pull_service` and a `StateManager`. Pre-populate the state file with `{"TICKET-1": {"local_hash": "A", "remote_hash": "B"}}`. Prepare a local Markdown file whose TICKET-1 content hashes to "C", and mock a Jira response for TICKET-1 that hashes to "D". (Act) Run the `pull` service. (Assert) The service returns a specific `ErrConflictDetected` error for TICKET-1.
* **Required Proof of Passing:** Console output from `go test` showing the `TestPullService_DetectsConflictState` test passing.
-* **Requirement:** **`USER-001`** - **Non-Interactive Error Handling** ([Link](./REQUIREMENTS-v2.md#USER-001))
+* **Requirement:** **`USER-001`** - **Non-Interactive Error Handling** ([Link](../development/REQUIREMENTS.md#user-001))
* **Test Case ID:** `TC-304.1`
* **Test Method Signature:** `func TestPushService_ProcessesAllAndReportsFailures(t *testing.T)`
* **Test Logic:** (Arrange) Create a Markdown file with three tickets. Mock the `JiraAdapter` to succeed on ticket 1 and 3, but fail on ticket 2. (Act) Run the `push` service without the `--force` flag. (Assert) The `ProcessResult` contains 2 successes and 1 failure. The service itself returns an error, but the mock confirms that API calls were attempted for all three tickets.
@@ -73,7 +73,7 @@ PASS
ok github.com/karolswdev/ticktr/internal/core/services 0.002s
```
* **Documentation:**
- * [x] **Documentation Updated:** Checked after the relevant documentation is updated. **Instruction:** `Update the HANDOFF-BEFORE-PHASE-3.md file, removing all sections related to "Backward Compatibility" and type aliases. State clearly that v2.0 is a breaking change.` **Evidence:** Updated section 1 of Critical Implementation Notes to state "v2.0 is a breaking change from v1.0. The legacy Story model and all related code paths have been removed."
+ * [x] **Documentation Updated:** Checked after the relevant documentation is updated. **Instruction:** `Update the HANDOFF-BEFORE-PHASE-3.md file, removing all sections related to "Backward Compatibility" and type aliases. State clearly that the final 1.0 format removes the Story-specific model.` **Evidence:** Updated section 1 of Critical Implementation Notes to state "The Story model and all related code paths have been removed."
2. **Task:** Integrate pre-flight validation directly into the `push` command.
* **Instruction:** `In cmd/ticketr/main.go, within the runPush function, add logic to instantiate the internal/core/validation.Validator. Before calling the push_service, execute a full validation pass on the parsed tickets. If any validation errors are found, print them to the console and os.Exit(1).`
@@ -165,7 +165,7 @@ ok github.com/karolswdev/ticktr/cmd/ticketr 0.002s
--- PASS: TestPushService_ProcessesAllAndReportsFailures (0.00s)
```
* **Documentation:**
- * [x] **Documentation Updated:** Checked after the relevant documentation is updated. **Instruction:** `Update the REQUIREMENTS-v2.md description for USER-001 to reflect that the tool processes all tickets and provides a summary report, exiting with an error code if any failures occurred.` **Evidence:** Updated USER-001 requirement at line 44 in REQUIREMENTS-v2.md.
+ * [x] **Documentation Updated:** Checked after the relevant documentation is updated. **Instruction:** `Update the requirements description for USER-001 to reflect that the tool processes all tickets and provides a summary report, exiting with an error code if any failures occurred.` **Evidence:** Updated USER-001 requirement in docs/development/REQUIREMENTS.md.
---
> ### **Story Completion: STORY-302**
@@ -216,4 +216,4 @@ ok github.com/karolswdev/ticktr/internal/renderer (cached)
ok github.com/karolswdev/ticktr/internal/state (cached)
```
-* **Final Instruction:** Once the `Final Full Regression Test Passed` checkbox above is marked `[x]`, your final action for this phase is to modify the main title of this document, changing `[ ] PHASE-3` to `[x] PHASE-3`. This concludes your work on this phase file.
\ No newline at end of file
+* **Final Instruction:** Once the `Final Full Regression Test Passed` checkbox above is marked `[x]`, your final action for this phase is to modify the main title of this document, changing `[ ] PHASE-3` to `[x] PHASE-3`. This concludes your work on this phase file.
diff --git a/docs/legacy/README.md b/docs/legacy/README.md
index 70f005d..61920f7 100644
--- a/docs/legacy/README.md
+++ b/docs/legacy/README.md
@@ -8,24 +8,24 @@ This directory contains deprecated documentation from earlier phases of the tick
### REQUIREMENTS-v1.md
-This is the original Software Requirements Specification (v1.0) from the project's inception. It has been superseded by `/REQUIREMENTS-v2.md` in the root directory.
+This is the original Software Requirements Specification drafted early in the project. It has been superseded by the consolidated requirements in `docs/development/REQUIREMENTS.md`.
**Status:** Deprecated
-**Superseded by:** [/REQUIREMENTS-v2.md](/REQUIREMENTS-v2.md)
+**Superseded by:** [docs/development/REQUIREMENTS.md](/docs/development/REQUIREMENTS.md)
## Migration Rationale
-The v1 requirements document was based on the original "Jira Story Creator" concept, which used a STORY-centric schema. As the project evolved, we recognized that:
+The early requirements document was based on the original "Jira Story Creator" concept, which used a STORY-centric schema. Before the 1.0 release we broadened the format so that:
-1. **Generic Ticket Schema:** Jira supports multiple issue types (Story, Task, Bug, Epic, etc.), not just Stories. The v1 schema was too narrow.
-2. **Flexibility:** The `# TICKET:` format in v2 allows users to specify any Jira issue type, making ticketr more versatile.
-3. **Consistency:** The v2 requirements align with the current codebase architecture (Hexagonal/Ports & Adapters) and operational model.
+1. **Generic Ticket Schema:** Jira supports multiple issue types (Story, Task, Bug, Epic, etc.), not just Stories. The story-only schema was too narrow.
+2. **Flexibility:** The unified `# TICKET:` format lets ticketr represent any Jira issue type while keeping a consistent structure.
+3. **Consistency:** The updated requirements align with the current codebase architecture (Hexagonal/Ports & Adapters) and operational model.
## Current Documentation
For current project requirements, architecture, and workflows, see:
-- [REQUIREMENTS-v2.md](/REQUIREMENTS-v2.md) - Current requirements specification
+- [docs/development/REQUIREMENTS.md](/docs/development/REQUIREMENTS.md) - Current requirements specification
- [ARCHITECTURE.md](/ARCHITECTURE.md) - System architecture and design
- [docs/WORKFLOW.md](/docs/WORKFLOW.md) - Developer workflows
- [CONTRIBUTING.md](/CONTRIBUTING.md) - Contribution guidelines
diff --git a/docs/migration-guide.md b/docs/migration-guide.md
deleted file mode 100644
index f000826..0000000
--- a/docs/migration-guide.md
+++ /dev/null
@@ -1,175 +0,0 @@
-# Migration Guide: Legacy STORY Format to TICKET Format
-
-## Overview
-
-Ticketr v2.0 introduces the generic `# TICKET:` schema, replacing the legacy `# STORY:` format. This guide explains how to migrate your existing Markdown files.
-
-## Why the Change?
-
-The generic `# TICKET:` schema supports multiple Jira issue types (stories, bugs, tasks, epics) while maintaining backward compatibility with hierarchical validation. The legacy `# STORY:` format was overly specific and didn't align with Jira's flexible issue type system.
-
-**Reference:** development/REQUIREMENTS.md (PROD-201)
-
-## Migration Methods
-
-### Option 1: Automated Migration (Recommended)
-
-Use the `ticketr migrate` command to automatically convert files:
-
-#### Dry-Run Mode (Preview Changes)
-```bash
-# Preview changes for a single file
-ticketr migrate path/to/your-story.md
-
-# Preview changes for multiple files
-ticketr migrate examples/*.md
-```
-
-#### Write Mode (Apply Changes)
-```bash
-# Apply changes to a single file
-ticketr migrate path/to/your-story.md --write
-
-# Apply changes to multiple files
-ticketr migrate examples/*.md --write
-```
-
-**How it works:**
-- Scans file for `# STORY:` patterns
-- Replaces with `# TICKET:`
-- Preserves all formatting, whitespace, and indentation
-- Reports number of changes made
-
-### Option 2: Manual Migration
-
-For simple cases, you can use find-replace in your text editor:
-
-1. Open the Markdown file
-2. Find: `# STORY:`
-3. Replace with: `# TICKET:`
-4. Save the file
-5. Verify with: `ticketr validate path/to/file.md`
-
-## Migration Checklist
-
-- [ ] Identify all Markdown files using legacy `# STORY:` format
-- [ ] Run `ticketr migrate ` in dry-run mode to preview changes
-- [ ] Review the preview to ensure changes are correct
-- [ ] Run `ticketr migrate --write` to apply changes
-- [ ] Run `ticketr validate ` to verify migrated files
-- [ ] Test your workflow with migrated files
-- [ ] Commit the changes to version control
-
-## Common Scenarios
-
-### Scenario 1: Single File Migration
-```bash
-ticketr migrate tickets/PROJ-123.md --write
-```
-
-### Scenario 2: Batch Migration (Entire Directory)
-```bash
-ticketr migrate tickets/*.md --write
-```
-
-### Scenario 3: Selective Migration
-```bash
-# Preview all files first
-ticketr migrate tickets/*.md
-
-# Migrate only specific files that need changes
-ticketr migrate tickets/old-story-1.md tickets/old-story-2.md --write
-```
-
-## Troubleshooting
-
-### Error: "Legacy '# STORY:' format detected"
-
-If you see this error when running `ticketr push`, it means your file hasn't been migrated yet:
-
-```
-Error: Legacy '# STORY:' format detected at line 1.
-Please migrate to '# TICKET:' format.
-See development/REQUIREMENTS.md (PROD-201) or use 'ticketr migrate ' command.
-```
-
-**Solution:** Run the migration command on the affected file:
-```bash
-ticketr migrate path/to/file.md --write
-```
-
-### Files Already Using # TICKET:
-
-If you run the migrate command on files already using `# TICKET:` format, the tool will report:
-```
-No changes needed for: path/to/file.md
-```
-
-### Mixed Formats in One File
-
-If a file contains both `# STORY:` and `# TICKET:` headers, the migration tool will convert all `# STORY:` instances to `# TICKET:`.
-
-## Rollback Strategy
-
-If you need to revert changes after migration:
-
-1. **Using Git:**
- ```bash
- git checkout -- path/to/file.md
- ```
-
-2. **Using Backup:**
- Before migrating, create backups:
- ```bash
- cp -r tickets/ tickets.backup/
- ```
-
-## Schema Differences
-
-The migration is straightforward - only the header keyword changes:
-
-**Before (Legacy):**
-```markdown
-# STORY: PROJ-123 Implement user authentication
-```
-
-**After (Canonical):**
-```markdown
-# TICKET: PROJ-123 Implement user authentication
-```
-
-All other fields remain identical:
-- Description
-- Acceptance Criteria
-- Tasks
-- Issue Type
-- Status
-- Assignee
-- etc.
-
-## Validation
-
-After migration, validate your files:
-
-```bash
-# Validate single file
-ticketr validate path/to/file.md
-
-# Validate multiple files
-ticketr validate tickets/*.md
-```
-
-## Additional Resources
-
-- **Schema Specification:** development/REQUIREMENTS.md (PROD-201)
-- **Parser Behavior:** The v2.0+ parser rejects `# STORY:` format with helpful error messages
-- **Test Fixtures:** Legacy samples in `testdata/legacy_story/` demonstrate rejected formats
-- **Examples:** See `examples/` directory for canonical format templates
-
-## Support
-
-If you encounter issues during migration:
-1. Check the error message for specific guidance
-2. Review development/REQUIREMENTS.md for schema details
-3. Run `ticketr help migrate` for command usage
-4. Create a GitHub issue with details if problems persist
diff --git a/docs/project-assessment-2025-10-16.md b/docs/project-assessment-2025-10-16.md
index f57ea5b..9614dc9 100644
--- a/docs/project-assessment-2025-10-16.md
+++ b/docs/project-assessment-2025-10-16.md
@@ -52,7 +52,7 @@ Ticketr demonstrates **exceptional** documentation quality and completeness for
| docs/WORKFLOW.md | ✅ | A+ | 379 lines - exceptional walkthrough |
| docs/release-process.md | ✅ | A+ | 475 lines - enterprise-grade |
| docs/style-guide.md | ✅ | A+ | 807 lines - comprehensive |
-| docs/migration-guide.md | ✅ | A | Good migration documentation |
+| docs/migration-guide.md | ❌ | - | Removed prior to 1.0; manual guidance lives in README/WORKFLOW |
| docs/state-management.md | ✅ | A | Technical deep-dive |
| docs/qa-checklist.md | ✅ | A | Professional QA process |
| docs/integration-testing-guide.md | ✅ | A | Detailed testing guide |
@@ -175,7 +175,7 @@ Ticketr demonstrates **exceptional** documentation quality and completeness for
- ARCHITECTURE.md is rare for CLI tools - shows maturity
- WORKFLOW.md provides end-to-end walkthroughs
- docs/style-guide.md ensures consistency (807 lines!)
-- Migration guide eases v1→v2 transition
+- Schema guidance ensures consistent `# TICKET:` usage
- Release process documentation is enterprise-grade
**Weaknesses:**
diff --git a/docs/qa-checklist.md b/docs/qa-checklist.md
index fc86b3c..7ccfcfd 100644
--- a/docs/qa-checklist.md
+++ b/docs/qa-checklist.md
@@ -463,7 +463,6 @@ gh pr checks
- **Smoke Tests:** `tests/smoke/README.md` - End-to-end smoke test documentation
- **Integration Testing:** `docs/integration-testing-guide.md` - JIRA integration test scenarios
- **State Management:** `docs/state-management.md` - State file operations
-- **Migration Guide:** `docs/migration-guide.md` - Migrating from v1.x to v2.x
---
diff --git a/docs/state-management.md b/docs/state-management.md
index cd96760..cb45659 100644
--- a/docs/state-management.md
+++ b/docs/state-management.md
@@ -116,7 +116,7 @@ When a conflict is detected, `ticketr pull` will:
**Issue: Tickets always detected as changed**
- **Cause**: Likely non-deterministic hashing (pre-Milestone 4)
-- **Solution**: Upgrade to v2.0+ or delete `.ticketr.state` and re-sync
+- **Solution**: Delete `.ticketr.state` and re-sync (format stabilized in 1.0)
**Issue: Conflicts on every pull**
- **Cause**: State file out of sync or missing
diff --git a/docs/style-guide.md b/docs/style-guide.md
index 3e5fc15..4b7d7f2 100644
--- a/docs/style-guide.md
+++ b/docs/style-guide.md
@@ -17,7 +17,7 @@ This guide establishes standards for writing, formatting, and maintaining docume
**Convention:** Use lowercase kebab-case with `.md` extension
**Examples:**
-- ✅ `migration-guide.md`
+- ✅ `workflow.md`
- ✅ `integration-testing-guide.md`
- ✅ `state-management.md`
- ❌ `MigrationGuide.md`
@@ -130,11 +130,11 @@ Available commands:
**Example:**
```markdown
-Migration steps:
+Release steps:
1. Preview changes with dry-run mode
2. Backup your files
-3. Apply migration with --write flag
+3. Tag the release and push
4. Verify results
```
@@ -168,7 +168,7 @@ Pre-release checklist:
**Format:**
```markdown
-See [Migration Guide](docs/migration-guide.md) for details.
+See [Workflow Guide](docs/WORKFLOW.md) for details.
See [development/REQUIREMENTS.md](development/REQUIREMENTS.md) for specifications.
See [Field Inheritance](README.md#field-inheritance) for examples.
```
@@ -356,14 +356,14 @@ logic is isolated from external dependencies through ports and adapters.
**Example:**
-In `migration-guide.md`:
+In `docs/WORKFLOW.md`:
```markdown
See [development/REQUIREMENTS.md](development/REQUIREMENTS.md) for schema specification (PROD-201).
```
In `development/REQUIREMENTS.md`:
```markdown
-**Migration Guide:** See [docs/migration-guide.md](docs/migration-guide.md)
+See [docs/WORKFLOW.md](docs/WORKFLOW.md) for end-to-end example flows.
```
### Section Anchors
@@ -637,7 +637,7 @@ architecture documentation for details.
**Commit Message Examples:**
```
-docs: update migration guide with batch processing examples
+docs: add workflow quickstart example
docs: fix broken link in CONTRIBUTING.md
docs: add troubleshooting section to state-management.md
```
@@ -660,7 +660,7 @@ docs: add troubleshooting section to state-management.md
**Deprecation:**
- Mark deprecated content clearly
-- Provide migration path
+- Explain how to update older content when formats change
- Archive to `docs/legacy/` or `docs/history/` when fully obsolete
---
@@ -775,7 +775,7 @@ Excellent examples demonstrating these standards:
- **README.md** - User-facing guide with clear structure, code examples, cross-references
- **docs/WORKFLOW.md** - End-to-end workflow guide with step-by-step instructions
- **docs/ci.md** - Comprehensive technical documentation with troubleshooting
-- **docs/migration-guide.md** - Procedural guide with clear steps and examples
+- **docs/WORKFLOW.md** - Procedural guide with clear steps and examples
- **ARCHITECTURE.md** - Technical reference with diagrams, tables, and cross-references
Study these documents when writing new documentation.
diff --git a/evidence/phase-1/STORY-1/baseline-tests.txt b/evidence/phase-1/STORY-1/baseline-tests.txt
deleted file mode 100644
index 5574d5f..0000000
--- a/evidence/phase-1/STORY-1/baseline-tests.txt
+++ /dev/null
@@ -1,40 +0,0 @@
-? github.com/karolswdev/ticktr/internal/core/domain [no test files]
-? github.com/karolswdev/ticktr/internal/core/ports [no test files]
-? github.com/karolswdev/ticktr/internal/core/services [no test files]
-=== RUN TestCLI_WithForceFlag_OnPartialError_UploadsValidTasks
---- PASS: TestCLI_WithForceFlag_OnPartialError_UploadsValidTasks (0.00s)
-=== RUN TestForcePartialUploadLogic
-=== RUN TestForcePartialUploadLogic/Force_flag_with_errors_-_should_not_exit_with_error
-=== RUN TestForcePartialUploadLogic/No_force_flag_with_errors_-_should_exit_with_error
-=== RUN TestForcePartialUploadLogic/Force_flag_without_errors_-_should_not_exit_with_error
-=== RUN TestForcePartialUploadLogic/No_force_flag_without_errors_-_should_not_exit_with_error
---- PASS: TestForcePartialUploadLogic (0.00s)
- --- PASS: TestForcePartialUploadLogic/Force_flag_with_errors_-_should_not_exit_with_error (0.00s)
- --- PASS: TestForcePartialUploadLogic/No_force_flag_with_errors_-_should_exit_with_error (0.00s)
- --- PASS: TestForcePartialUploadLogic/Force_flag_without_errors_-_should_not_exit_with_error (0.00s)
- --- PASS: TestForcePartialUploadLogic/No_force_flag_without_errors_-_should_not_exit_with_error (0.00s)
-=== RUN TestVerboseFlagOutput
---- PASS: TestVerboseFlagOutput (0.00s)
-PASS
-ok github.com/karolswdev/ticktr/cmd/ticketr 0.008s
-=== RUN TestParser_ParseInput_ValidFile_ReturnsCorrectStoryCount
---- PASS: TestParser_ParseInput_ValidFile_ReturnsCorrectStoryCount (0.00s)
-=== RUN TestParser_ParseInput_TaskWithDetails_CorrectlyPopulatesTaskFields
---- PASS: TestParser_ParseInput_TaskWithDetails_CorrectlyPopulatesTaskFields (0.00s)
-=== RUN TestParser_ParseInput_WithAndWithoutJiraKeys_CorrectlyPopulatesIDs
---- PASS: TestParser_ParseInput_WithAndWithoutJiraKeys_CorrectlyPopulatesIDs (0.00s)
-=== RUN TestParser_ParseInput_MalformedStoryHeading_ReturnsErrorAndNoStories
---- PASS: TestParser_ParseInput_MalformedStoryHeading_ReturnsErrorAndNoStories (0.00s)
-PASS
-ok github.com/karolswdev/ticktr/internal/adapters/filesystem 0.008s
-=== RUN TestJiraAdapter_NewClient_WithEnvVars_AuthenticatesSuccessfully
---- PASS: TestJiraAdapter_NewClient_WithEnvVars_AuthenticatesSuccessfully (0.27s)
-=== RUN TestJiraAdapter_CreateStory_ValidStory_ReturnsNewJiraID
- jira_adapter_test.go:61: Failed to create story: failed to create story with status 400: {"errorMessages":[],"errors":{"issuetype":"The issue type selected is invalid."}}
---- FAIL: TestJiraAdapter_CreateStory_ValidStory_ReturnsNewJiraID (0.46s)
-=== RUN TestJiraAdapter_UpdateStory_ValidStoryWithID_Succeeds
- jira_adapter_test.go:97: Failed to create initial story: failed to create story with status 400: {"errorMessages":[],"errors":{"issuetype":"The issue type selected is invalid."}}
---- FAIL: TestJiraAdapter_UpdateStory_ValidStoryWithID_Succeeds (0.41s)
-FAIL
-FAIL github.com/karolswdev/ticktr/internal/adapters/jira 1.160s
-FAIL
diff --git a/evidence/phase-1/STORY-1/story-final-commit.txt b/evidence/phase-1/STORY-1/story-final-commit.txt
deleted file mode 100644
index 0f078c9..0000000
--- a/evidence/phase-1/STORY-1/story-final-commit.txt
+++ /dev/null
@@ -1 +0,0 @@
-b156b44eaf68c04bff6dd340b97de9dce4649f02
diff --git a/evidence/phase-1/STORY-1/story-regression-final.txt b/evidence/phase-1/STORY-1/story-regression-final.txt
deleted file mode 100644
index fde2d64..0000000
--- a/evidence/phase-1/STORY-1/story-regression-final.txt
+++ /dev/null
@@ -1,47 +0,0 @@
-? github.com/karolswdev/ticktr/internal/core/domain [no test files]
-? github.com/karolswdev/ticktr/internal/core/ports [no test files]
-? github.com/karolswdev/ticktr/internal/core/services [no test files]
-=== RUN TestCLI_WithForceFlag_OnPartialError_UploadsValidTasks
---- PASS: TestCLI_WithForceFlag_OnPartialError_UploadsValidTasks (0.00s)
-=== RUN TestForcePartialUploadLogic
-=== RUN TestForcePartialUploadLogic/Force_flag_with_errors_-_should_not_exit_with_error
-=== RUN TestForcePartialUploadLogic/No_force_flag_with_errors_-_should_exit_with_error
-=== RUN TestForcePartialUploadLogic/Force_flag_without_errors_-_should_not_exit_with_error
-=== RUN TestForcePartialUploadLogic/No_force_flag_without_errors_-_should_not_exit_with_error
---- PASS: TestForcePartialUploadLogic (0.00s)
- --- PASS: TestForcePartialUploadLogic/Force_flag_with_errors_-_should_not_exit_with_error (0.00s)
- --- PASS: TestForcePartialUploadLogic/No_force_flag_with_errors_-_should_exit_with_error (0.00s)
- --- PASS: TestForcePartialUploadLogic/Force_flag_without_errors_-_should_not_exit_with_error (0.00s)
- --- PASS: TestForcePartialUploadLogic/No_force_flag_without_errors_-_should_not_exit_with_error (0.00s)
-=== RUN TestVerboseFlagOutput
---- PASS: TestVerboseFlagOutput (0.00s)
-PASS
-ok github.com/karolswdev/ticktr/cmd/ticketr 0.002s
-=== RUN TestParser_ParseInput_ValidFile_ReturnsCorrectStoryCount
---- PASS: TestParser_ParseInput_ValidFile_ReturnsCorrectStoryCount (0.00s)
-=== RUN TestParser_ParseInput_TaskWithDetails_CorrectlyPopulatesTaskFields
---- PASS: TestParser_ParseInput_TaskWithDetails_CorrectlyPopulatesTaskFields (0.00s)
-=== RUN TestParser_ParseInput_WithAndWithoutJiraKeys_CorrectlyPopulatesIDs
---- PASS: TestParser_ParseInput_WithAndWithoutJiraKeys_CorrectlyPopulatesIDs (0.00s)
-=== RUN TestParser_ParseInput_MalformedStoryHeading_ReturnsErrorAndNoStories
---- PASS: TestParser_ParseInput_MalformedStoryHeading_ReturnsErrorAndNoStories (0.00s)
-PASS
-ok github.com/karolswdev/ticktr/internal/adapters/filesystem 0.002s
-=== RUN TestJiraAdapter_NewClient_WithEnvVars_AuthenticatesSuccessfully
---- PASS: TestJiraAdapter_NewClient_WithEnvVars_AuthenticatesSuccessfully (0.26s)
-=== RUN TestJiraAdapter_CreateStory_ValidStory_ReturnsNewJiraID
- jira_adapter_test.go:61: Failed to create story: failed to create story with status 400: {"errorMessages":[],"errors":{"issuetype":"The issue type selected is invalid."}}
---- FAIL: TestJiraAdapter_CreateStory_ValidStory_ReturnsNewJiraID (0.27s)
-=== RUN TestJiraAdapter_UpdateStory_ValidStoryWithID_Succeeds
- jira_adapter_test.go:97: Failed to create initial story: failed to create story with status 400: {"errorMessages":[],"errors":{"issuetype":"The issue type selected is invalid."}}
---- FAIL: TestJiraAdapter_UpdateStory_ValidStoryWithID_Succeeds (0.30s)
-FAIL
-FAIL github.com/karolswdev/ticktr/internal/adapters/jira 0.836s
-=== RUN TestParser_RecognizesTicketBlock
---- PASS: TestParser_RecognizesTicketBlock (0.00s)
-=== RUN TestParser_ParsesNestedTasks
- parser_test.go:72: Expected 2 tasks, got 1
---- FAIL: TestParser_ParsesNestedTasks (0.00s)
-FAIL
-FAIL github.com/karolswdev/ticktr/internal/parser 0.002s
-FAIL
diff --git a/evidence/phase-1/STORY-1/story-regression.txt b/evidence/phase-1/STORY-1/story-regression.txt
deleted file mode 100644
index 54614bd..0000000
--- a/evidence/phase-1/STORY-1/story-regression.txt
+++ /dev/null
@@ -1,50 +0,0 @@
-=== RUN TestCLI_WithForceFlag_OnPartialError_UploadsValidTasks
---- PASS: TestCLI_WithForceFlag_OnPartialError_UploadsValidTasks (0.00s)
-=== RUN TestForcePartialUploadLogic
-=== RUN TestForcePartialUploadLogic/Force_flag_with_errors_-_should_not_exit_with_error
-=== RUN TestForcePartialUploadLogic/No_force_flag_with_errors_-_should_exit_with_error
-=== RUN TestForcePartialUploadLogic/Force_flag_without_errors_-_should_not_exit_with_error
-=== RUN TestForcePartialUploadLogic/No_force_flag_without_errors_-_should_not_exit_with_error
---- PASS: TestForcePartialUploadLogic (0.00s)
- --- PASS: TestForcePartialUploadLogic/Force_flag_with_errors_-_should_not_exit_with_error (0.00s)
- --- PASS: TestForcePartialUploadLogic/No_force_flag_with_errors_-_should_exit_with_error (0.00s)
- --- PASS: TestForcePartialUploadLogic/Force_flag_without_errors_-_should_not_exit_with_error (0.00s)
- --- PASS: TestForcePartialUploadLogic/No_force_flag_without_errors_-_should_not_exit_with_error (0.00s)
-=== RUN TestVerboseFlagOutput
---- PASS: TestVerboseFlagOutput (0.00s)
-PASS
-ok github.com/karolswdev/ticktr/cmd/ticketr 0.002s
-=== RUN TestParser_ParseInput_ValidFile_ReturnsCorrectStoryCount
- file_repository_test.go:60: Expected 2 stories, got 0
---- FAIL: TestParser_ParseInput_ValidFile_ReturnsCorrectStoryCount (0.00s)
-=== RUN TestParser_ParseInput_TaskWithDetails_CorrectlyPopulatesTaskFields
- file_repository_test.go:101: Expected 1 story, got 0
---- FAIL: TestParser_ParseInput_TaskWithDetails_CorrectlyPopulatesTaskFields (0.00s)
-=== RUN TestParser_ParseInput_WithAndWithoutJiraKeys_CorrectlyPopulatesIDs
- file_repository_test.go:162: Expected 2 stories, got 0
---- FAIL: TestParser_ParseInput_WithAndWithoutJiraKeys_CorrectlyPopulatesIDs (0.00s)
-=== RUN TestParser_ParseInput_MalformedStoryHeading_ReturnsErrorAndNoStories
- file_repository_test.go:223: Expected an error for malformed story heading, got nil
---- FAIL: TestParser_ParseInput_MalformedStoryHeading_ReturnsErrorAndNoStories (0.00s)
-FAIL
-FAIL github.com/karolswdev/ticktr/internal/adapters/filesystem 0.002s
-? github.com/karolswdev/ticktr/internal/core/domain [no test files]
-? github.com/karolswdev/ticktr/internal/core/ports [no test files]
-? github.com/karolswdev/ticktr/internal/core/services [no test files]
-=== RUN TestJiraAdapter_NewClient_WithEnvVars_AuthenticatesSuccessfully
---- PASS: TestJiraAdapter_NewClient_WithEnvVars_AuthenticatesSuccessfully (0.28s)
-=== RUN TestJiraAdapter_CreateStory_ValidStory_ReturnsNewJiraID
- jira_adapter_test.go:61: Failed to create story: failed to create story with status 400: {"errorMessages":[],"errors":{"issuetype":"The issue type selected is invalid."}}
---- FAIL: TestJiraAdapter_CreateStory_ValidStory_ReturnsNewJiraID (0.35s)
-=== RUN TestJiraAdapter_UpdateStory_ValidStoryWithID_Succeeds
- jira_adapter_test.go:97: Failed to create initial story: failed to create story with status 400: {"errorMessages":[],"errors":{"issuetype":"The issue type selected is invalid."}}
---- FAIL: TestJiraAdapter_UpdateStory_ValidStoryWithID_Succeeds (0.34s)
-FAIL
-FAIL github.com/karolswdev/ticktr/internal/adapters/jira 0.974s
-=== RUN TestParser_RecognizesTicketBlock
---- PASS: TestParser_RecognizesTicketBlock (0.00s)
-=== RUN TestParser_ParsesNestedTasks
---- PASS: TestParser_ParsesNestedTasks (0.00s)
-PASS
-ok github.com/karolswdev/ticktr/internal/parser 0.002s
-FAIL
diff --git a/evidence/phase-1/STORY-1/task-1-commit.txt b/evidence/phase-1/STORY-1/task-1-commit.txt
deleted file mode 100644
index bcb5615..0000000
--- a/evidence/phase-1/STORY-1/task-1-commit.txt
+++ /dev/null
@@ -1 +0,0 @@
-b475d872fe72c98ed6fad39b8cd2989a13150f0f
diff --git a/evidence/phase-1/STORY-1/task-2-commit.txt b/evidence/phase-1/STORY-1/task-2-commit.txt
deleted file mode 100644
index 4b80529..0000000
--- a/evidence/phase-1/STORY-1/task-2-commit.txt
+++ /dev/null
@@ -1 +0,0 @@
-40073cb454e5d280a7e5bde623ab2c79f0a04134
diff --git a/evidence/phase-1/STORY-1/task-2-tc201.1-post.txt b/evidence/phase-1/STORY-1/task-2-tc201.1-post.txt
deleted file mode 100644
index a7ca7a0..0000000
--- a/evidence/phase-1/STORY-1/task-2-tc201.1-post.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-=== RUN TestParser_RecognizesTicketBlock
---- PASS: TestParser_RecognizesTicketBlock (0.00s)
-PASS
-ok github.com/karolswdev/ticktr/internal/parser 0.001s
diff --git a/evidence/phase-1/STORY-1/task-2-tc201.2-post.txt b/evidence/phase-1/STORY-1/task-2-tc201.2-post.txt
deleted file mode 100644
index ae705a5..0000000
--- a/evidence/phase-1/STORY-1/task-2-tc201.2-post.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-=== RUN TestParser_ParsesNestedTasks
---- PASS: TestParser_ParsesNestedTasks (0.00s)
-PASS
-ok github.com/karolswdev/ticktr/internal/parser 0.001s
diff --git a/evidence/phase-1/STORY-2/baseline-tests.txt b/evidence/phase-1/STORY-2/baseline-tests.txt
deleted file mode 100644
index 050167f..0000000
--- a/evidence/phase-1/STORY-2/baseline-tests.txt
+++ /dev/null
@@ -1,46 +0,0 @@
-=== RUN TestCLI_WithForceFlag_OnPartialError_UploadsValidTasks
---- PASS: TestCLI_WithForceFlag_OnPartialError_UploadsValidTasks (0.00s)
-=== RUN TestForcePartialUploadLogic
-=== RUN TestForcePartialUploadLogic/Force_flag_with_errors_-_should_not_exit_with_error
-=== RUN TestForcePartialUploadLogic/No_force_flag_with_errors_-_should_exit_with_error
-=== RUN TestForcePartialUploadLogic/Force_flag_without_errors_-_should_not_exit_with_error
-=== RUN TestForcePartialUploadLogic/No_force_flag_without_errors_-_should_not_exit_with_error
---- PASS: TestForcePartialUploadLogic (0.00s)
- --- PASS: TestForcePartialUploadLogic/Force_flag_with_errors_-_should_not_exit_with_error (0.00s)
- --- PASS: TestForcePartialUploadLogic/No_force_flag_with_errors_-_should_exit_with_error (0.00s)
- --- PASS: TestForcePartialUploadLogic/Force_flag_without_errors_-_should_not_exit_with_error (0.00s)
- --- PASS: TestForcePartialUploadLogic/No_force_flag_without_errors_-_should_not_exit_with_error (0.00s)
-=== RUN TestVerboseFlagOutput
---- PASS: TestVerboseFlagOutput (0.00s)
-PASS
-ok github.com/karolswdev/ticktr/cmd/ticketr 0.002s
-=== RUN TestParser_ParseInput_ValidFile_ReturnsCorrectStoryCount
---- PASS: TestParser_ParseInput_ValidFile_ReturnsCorrectStoryCount (0.00s)
-=== RUN TestParser_ParseInput_TaskWithDetails_CorrectlyPopulatesTaskFields
---- PASS: TestParser_ParseInput_TaskWithDetails_CorrectlyPopulatesTaskFields (0.00s)
-=== RUN TestParser_ParseInput_WithAndWithoutJiraKeys_CorrectlyPopulatesIDs
---- PASS: TestParser_ParseInput_WithAndWithoutJiraKeys_CorrectlyPopulatesIDs (0.00s)
-=== RUN TestParser_ParseInput_MalformedStoryHeading_ReturnsErrorAndNoStories
---- PASS: TestParser_ParseInput_MalformedStoryHeading_ReturnsErrorAndNoStories (0.00s)
-PASS
-ok github.com/karolswdev/ticktr/internal/adapters/filesystem 0.002s
-? github.com/karolswdev/ticktr/internal/core/domain [no test files]
-? github.com/karolswdev/ticktr/internal/core/ports [no test files]
-? github.com/karolswdev/ticktr/internal/core/services [no test files]
-=== RUN TestJiraAdapter_NewClient_WithEnvVars_AuthenticatesSuccessfully
---- PASS: TestJiraAdapter_NewClient_WithEnvVars_AuthenticatesSuccessfully (0.26s)
-=== RUN TestJiraAdapter_CreateStory_ValidStory_ReturnsNewJiraID
- jira_adapter_test.go:61: Failed to create story: failed to create story with status 400: {"errorMessages":[],"errors":{"issuetype":"The issue type selected is invalid."}}
---- FAIL: TestJiraAdapter_CreateStory_ValidStory_ReturnsNewJiraID (0.29s)
-=== RUN TestJiraAdapter_UpdateStory_ValidStoryWithID_Succeeds
- jira_adapter_test.go:97: Failed to create initial story: failed to create story with status 400: {"errorMessages":[],"errors":{"issuetype":"The issue type selected is invalid."}}
---- FAIL: TestJiraAdapter_UpdateStory_ValidStoryWithID_Succeeds (0.29s)
-FAIL
-FAIL github.com/karolswdev/ticktr/internal/adapters/jira 0.847s
-=== RUN TestParser_RecognizesTicketBlock
---- PASS: TestParser_RecognizesTicketBlock (0.00s)
-=== RUN TestParser_ParsesNestedTasks
---- PASS: TestParser_ParsesNestedTasks (0.00s)
-PASS
-ok github.com/karolswdev/ticktr/internal/parser 0.001s
-FAIL
diff --git a/evidence/phase-1/STORY-2/story-final-commit.txt b/evidence/phase-1/STORY-2/story-final-commit.txt
deleted file mode 100644
index abb98b8..0000000
--- a/evidence/phase-1/STORY-2/story-final-commit.txt
+++ /dev/null
@@ -1 +0,0 @@
-ea4aeaec30f0b212d7541a77fca66f0b3e98a56c
diff --git a/evidence/phase-1/STORY-2/story-regression.txt b/evidence/phase-1/STORY-2/story-regression.txt
deleted file mode 100644
index 23b89e0..0000000
--- a/evidence/phase-1/STORY-2/story-regression.txt
+++ /dev/null
@@ -1,51 +0,0 @@
-? github.com/karolswdev/ticktr/internal/core/domain [no test files]
-? github.com/karolswdev/ticktr/internal/core/ports [no test files]
-=== RUN TestCLI_WithForceFlag_OnPartialError_UploadsValidTasks
---- PASS: TestCLI_WithForceFlag_OnPartialError_UploadsValidTasks (0.00s)
-=== RUN TestForcePartialUploadLogic
-=== RUN TestForcePartialUploadLogic/Force_flag_with_errors_-_should_not_exit_with_error
-=== RUN TestForcePartialUploadLogic/No_force_flag_with_errors_-_should_exit_with_error
-=== RUN TestForcePartialUploadLogic/Force_flag_without_errors_-_should_not_exit_with_error
-=== RUN TestForcePartialUploadLogic/No_force_flag_without_errors_-_should_not_exit_with_error
---- PASS: TestForcePartialUploadLogic (0.00s)
- --- PASS: TestForcePartialUploadLogic/Force_flag_with_errors_-_should_not_exit_with_error (0.00s)
- --- PASS: TestForcePartialUploadLogic/No_force_flag_with_errors_-_should_exit_with_error (0.00s)
- --- PASS: TestForcePartialUploadLogic/Force_flag_without_errors_-_should_not_exit_with_error (0.00s)
- --- PASS: TestForcePartialUploadLogic/No_force_flag_without_errors_-_should_not_exit_with_error (0.00s)
-=== RUN TestVerboseFlagOutput
---- PASS: TestVerboseFlagOutput (0.00s)
-=== RUN TestCli_ReadsConfigAndDefaults
---- PASS: TestCli_ReadsConfigAndDefaults (0.00s)
-PASS
-ok github.com/karolswdev/ticktr/cmd/ticketr 0.003s
-=== RUN TestParser_ParseInput_ValidFile_ReturnsCorrectStoryCount
---- PASS: TestParser_ParseInput_ValidFile_ReturnsCorrectStoryCount (0.00s)
-=== RUN TestParser_ParseInput_TaskWithDetails_CorrectlyPopulatesTaskFields
---- PASS: TestParser_ParseInput_TaskWithDetails_CorrectlyPopulatesTaskFields (0.00s)
-=== RUN TestParser_ParseInput_WithAndWithoutJiraKeys_CorrectlyPopulatesIDs
---- PASS: TestParser_ParseInput_WithAndWithoutJiraKeys_CorrectlyPopulatesIDs (0.00s)
-=== RUN TestParser_ParseInput_MalformedStoryHeading_ReturnsErrorAndNoStories
---- PASS: TestParser_ParseInput_MalformedStoryHeading_ReturnsErrorAndNoStories (0.00s)
-PASS
-ok github.com/karolswdev/ticktr/internal/adapters/filesystem 0.002s
-=== RUN TestJiraAdapter_NewClient_WithEnvVars_AuthenticatesSuccessfully
---- PASS: TestJiraAdapter_NewClient_WithEnvVars_AuthenticatesSuccessfully (0.28s)
-=== RUN TestJiraAdapter_CreateStory_ValidStory_ReturnsNewJiraID
- jira_adapter_test.go:61: Failed to create story: failed to create story with status 400: {"errorMessages":[],"errors":{"issuetype":"The issue type selected is invalid."}}
---- FAIL: TestJiraAdapter_CreateStory_ValidStory_ReturnsNewJiraID (0.27s)
-=== RUN TestJiraAdapter_UpdateStory_ValidStoryWithID_Succeeds
- jira_adapter_test.go:97: Failed to create initial story: failed to create story with status 400: {"errorMessages":[],"errors":{"issuetype":"The issue type selected is invalid."}}
---- FAIL: TestJiraAdapter_UpdateStory_ValidStoryWithID_Succeeds (0.28s)
-FAIL
-FAIL github.com/karolswdev/ticktr/internal/adapters/jira 0.833s
-=== RUN TestTicketService_CalculateFinalFields
---- PASS: TestTicketService_CalculateFinalFields (0.00s)
-PASS
-ok github.com/karolswdev/ticktr/internal/core/services 0.001s
-=== RUN TestParser_RecognizesTicketBlock
---- PASS: TestParser_RecognizesTicketBlock (0.00s)
-=== RUN TestParser_ParsesNestedTasks
---- PASS: TestParser_ParsesNestedTasks (0.00s)
-PASS
-ok github.com/karolswdev/ticktr/internal/parser 0.002s
-FAIL
diff --git a/evidence/phase-1/STORY-2/task-1-commit.txt b/evidence/phase-1/STORY-2/task-1-commit.txt
deleted file mode 100644
index e8da692..0000000
--- a/evidence/phase-1/STORY-2/task-1-commit.txt
+++ /dev/null
@@ -1 +0,0 @@
-81a36eb09e0532daf803a0ebe174d849ee791196
diff --git a/evidence/phase-1/STORY-2/task-1-tc202.1-post.txt b/evidence/phase-1/STORY-2/task-1-tc202.1-post.txt
deleted file mode 100644
index 1a094f7..0000000
--- a/evidence/phase-1/STORY-2/task-1-tc202.1-post.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-=== RUN TestTicketService_CalculateFinalFields
---- PASS: TestTicketService_CalculateFinalFields (0.00s)
-PASS
-ok github.com/karolswdev/ticktr/internal/core/services 0.001s
diff --git a/evidence/phase-1/STORY-2/task-2-commit.txt b/evidence/phase-1/STORY-2/task-2-commit.txt
deleted file mode 100644
index 814d23f..0000000
--- a/evidence/phase-1/STORY-2/task-2-commit.txt
+++ /dev/null
@@ -1 +0,0 @@
-081ceb54498986233a2aca6f1fcda0637ff4ffb7
diff --git a/evidence/phase-1/STORY-2/task-2-tc201.1-post.txt b/evidence/phase-1/STORY-2/task-2-tc201.1-post.txt
deleted file mode 100644
index 9456e15..0000000
--- a/evidence/phase-1/STORY-2/task-2-tc201.1-post.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-=== RUN TestCli_ReadsConfigAndDefaults
---- PASS: TestCli_ReadsConfigAndDefaults (0.00s)
-PASS
-ok github.com/karolswdev/ticktr/cmd/ticketr 0.002s
diff --git a/evidence/phase-1/phase-regression.txt b/evidence/phase-1/phase-regression.txt
deleted file mode 100644
index a1d7c6b..0000000
--- a/evidence/phase-1/phase-regression.txt
+++ /dev/null
@@ -1,51 +0,0 @@
-? github.com/karolswdev/ticktr/internal/core/domain [no test files]
-? github.com/karolswdev/ticktr/internal/core/ports [no test files]
-=== RUN TestCLI_WithForceFlag_OnPartialError_UploadsValidTasks
---- PASS: TestCLI_WithForceFlag_OnPartialError_UploadsValidTasks (0.00s)
-=== RUN TestForcePartialUploadLogic
-=== RUN TestForcePartialUploadLogic/Force_flag_with_errors_-_should_not_exit_with_error
-=== RUN TestForcePartialUploadLogic/No_force_flag_with_errors_-_should_exit_with_error
-=== RUN TestForcePartialUploadLogic/Force_flag_without_errors_-_should_not_exit_with_error
-=== RUN TestForcePartialUploadLogic/No_force_flag_without_errors_-_should_not_exit_with_error
---- PASS: TestForcePartialUploadLogic (0.00s)
- --- PASS: TestForcePartialUploadLogic/Force_flag_with_errors_-_should_not_exit_with_error (0.00s)
- --- PASS: TestForcePartialUploadLogic/No_force_flag_with_errors_-_should_exit_with_error (0.00s)
- --- PASS: TestForcePartialUploadLogic/Force_flag_without_errors_-_should_not_exit_with_error (0.00s)
- --- PASS: TestForcePartialUploadLogic/No_force_flag_without_errors_-_should_not_exit_with_error (0.00s)
-=== RUN TestVerboseFlagOutput
---- PASS: TestVerboseFlagOutput (0.00s)
-=== RUN TestCli_ReadsConfigAndDefaults
---- PASS: TestCli_ReadsConfigAndDefaults (0.00s)
-PASS
-ok github.com/karolswdev/ticktr/cmd/ticketr 0.003s
-=== RUN TestParser_ParseInput_ValidFile_ReturnsCorrectStoryCount
---- PASS: TestParser_ParseInput_ValidFile_ReturnsCorrectStoryCount (0.00s)
-=== RUN TestParser_ParseInput_TaskWithDetails_CorrectlyPopulatesTaskFields
---- PASS: TestParser_ParseInput_TaskWithDetails_CorrectlyPopulatesTaskFields (0.00s)
-=== RUN TestParser_ParseInput_WithAndWithoutJiraKeys_CorrectlyPopulatesIDs
---- PASS: TestParser_ParseInput_WithAndWithoutJiraKeys_CorrectlyPopulatesIDs (0.00s)
-=== RUN TestParser_ParseInput_MalformedStoryHeading_ReturnsErrorAndNoStories
---- PASS: TestParser_ParseInput_MalformedStoryHeading_ReturnsErrorAndNoStories (0.00s)
-PASS
-ok github.com/karolswdev/ticktr/internal/adapters/filesystem 0.002s
-=== RUN TestJiraAdapter_NewClient_WithEnvVars_AuthenticatesSuccessfully
---- PASS: TestJiraAdapter_NewClient_WithEnvVars_AuthenticatesSuccessfully (0.26s)
-=== RUN TestJiraAdapter_CreateStory_ValidStory_ReturnsNewJiraID
- jira_adapter_test.go:61: Failed to create story: failed to create story with status 400: {"errorMessages":[],"errors":{"issuetype":"The issue type selected is invalid."}}
---- FAIL: TestJiraAdapter_CreateStory_ValidStory_ReturnsNewJiraID (0.35s)
-=== RUN TestJiraAdapter_UpdateStory_ValidStoryWithID_Succeeds
- jira_adapter_test.go:97: Failed to create initial story: failed to create story with status 400: {"errorMessages":[],"errors":{"issuetype":"The issue type selected is invalid."}}
---- FAIL: TestJiraAdapter_UpdateStory_ValidStoryWithID_Succeeds (0.29s)
-FAIL
-FAIL github.com/karolswdev/ticktr/internal/adapters/jira 0.904s
-=== RUN TestTicketService_CalculateFinalFields
---- PASS: TestTicketService_CalculateFinalFields (0.00s)
-PASS
-ok github.com/karolswdev/ticktr/internal/core/services 0.001s
-=== RUN TestParser_RecognizesTicketBlock
---- PASS: TestParser_RecognizesTicketBlock (0.00s)
-=== RUN TestParser_ParsesNestedTasks
---- PASS: TestParser_ParsesNestedTasks (0.00s)
-PASS
-ok github.com/karolswdev/ticktr/internal/parser 0.001s
-FAIL
diff --git a/evidence/phase-2/STORY-3/commit.txt b/evidence/phase-2/STORY-3/commit.txt
deleted file mode 100644
index 28fc0c0..0000000
--- a/evidence/phase-2/STORY-3/commit.txt
+++ /dev/null
@@ -1 +0,0 @@
-31dc15a0635b2ed69229b1460bbd338db6503153
diff --git a/evidence/phase-2/STORY-3/readme-diff.txt b/evidence/phase-2/STORY-3/readme-diff.txt
deleted file mode 100644
index 2aaee1e..0000000
--- a/evidence/phase-2/STORY-3/readme-diff.txt
+++ /dev/null
@@ -1,52 +0,0 @@
-diff --git a/README.md b/README.md
-index 8cb827f..0337b79 100644
---- a/README.md
-+++ b/README.md
-@@ -113,18 +113,43 @@ Simply edit your file and run the tool again - it intelligently handles updates:
-
- ```bash
- # Basic operation
--ticketr -f stories.md
-+ticketr push stories.md
-
- # Verbose output for debugging
--ticketr -f stories.md --verbose
-+ticketr push stories.md --verbose
-
- # Continue on errors (CI/CD mode)
--ticketr -f stories.md --force-partial-upload
-+ticketr push stories.md --force-partial-upload
-+
-+# Discover JIRA schema and generate configuration
-+ticketr schema > .ticketr.yaml
-
--# Combine options
-+# Legacy mode (backward compatibility)
- ticketr -f stories.md -v --force-partial-upload
- ```
-
-+### Schema Discovery
-+
-+The `ticketr schema` command helps you discover available fields in your JIRA instance and generate a proper configuration file:
-+
-+```bash
-+# Discover fields and generate configuration
-+ticketr schema > .ticketr.yaml
-+
-+# View available fields with verbose output
-+ticketr schema -v
-+
-+# The command will output field mappings like:
-+# field_mappings:
-+# "Story Points":
-+# id: "customfield_10010"
-+# type: "number"
-+# "Sprint": "customfield_10020"
-+# "Epic Link": "customfield_10014"
-+```
-+
-+This is especially useful when working with custom fields that vary between JIRA instances.
-+
- ### Docker Usage
-
- Build and run using Docker:
diff --git a/evidence/phase-2/STORY-3/regression.txt b/evidence/phase-2/STORY-3/regression.txt
deleted file mode 100644
index a80e796..0000000
--- a/evidence/phase-2/STORY-3/regression.txt
+++ /dev/null
@@ -1,53 +0,0 @@
-? github.com/karolswdev/ticktr/internal/core/domain [no test files]
-? github.com/karolswdev/ticktr/internal/core/ports [no test files]
-=== RUN TestCLI_WithForceFlag_OnPartialError_UploadsValidTasks
---- PASS: TestCLI_WithForceFlag_OnPartialError_UploadsValidTasks (0.00s)
-=== RUN TestForcePartialUploadLogic
-=== RUN TestForcePartialUploadLogic/Force_flag_with_errors_-_should_not_exit_with_error
-=== RUN TestForcePartialUploadLogic/No_force_flag_with_errors_-_should_exit_with_error
-=== RUN TestForcePartialUploadLogic/Force_flag_without_errors_-_should_not_exit_with_error
-=== RUN TestForcePartialUploadLogic/No_force_flag_without_errors_-_should_not_exit_with_error
---- PASS: TestForcePartialUploadLogic (0.00s)
- --- PASS: TestForcePartialUploadLogic/Force_flag_with_errors_-_should_not_exit_with_error (0.00s)
- --- PASS: TestForcePartialUploadLogic/No_force_flag_with_errors_-_should_exit_with_error (0.00s)
- --- PASS: TestForcePartialUploadLogic/Force_flag_without_errors_-_should_not_exit_with_error (0.00s)
- --- PASS: TestForcePartialUploadLogic/No_force_flag_without_errors_-_should_not_exit_with_error (0.00s)
-=== RUN TestVerboseFlagOutput
---- PASS: TestVerboseFlagOutput (0.00s)
-=== RUN TestCli_ReadsConfigAndDefaults
---- PASS: TestCli_ReadsConfigAndDefaults (0.00s)
-=== RUN TestSchemaCmd_GeneratesValidYaml
---- PASS: TestSchemaCmd_GeneratesValidYaml (0.00s)
-PASS
-ok github.com/karolswdev/ticktr/cmd/ticketr 0.002s
-=== RUN TestParser_ParseInput_ValidFile_ReturnsCorrectStoryCount
---- PASS: TestParser_ParseInput_ValidFile_ReturnsCorrectStoryCount (0.00s)
-=== RUN TestParser_ParseInput_TaskWithDetails_CorrectlyPopulatesTaskFields
---- PASS: TestParser_ParseInput_TaskWithDetails_CorrectlyPopulatesTaskFields (0.00s)
-=== RUN TestParser_ParseInput_WithAndWithoutJiraKeys_CorrectlyPopulatesIDs
---- PASS: TestParser_ParseInput_WithAndWithoutJiraKeys_CorrectlyPopulatesIDs (0.00s)
-=== RUN TestParser_ParseInput_MalformedStoryHeading_ReturnsErrorAndNoStories
---- PASS: TestParser_ParseInput_MalformedStoryHeading_ReturnsErrorAndNoStories (0.00s)
-PASS
-ok github.com/karolswdev/ticktr/internal/adapters/filesystem 0.002s
-=== RUN TestJiraAdapter_NewClient_WithEnvVars_AuthenticatesSuccessfully
---- PASS: TestJiraAdapter_NewClient_WithEnvVars_AuthenticatesSuccessfully (0.40s)
-=== RUN TestJiraAdapter_CreateStory_ValidStory_ReturnsNewJiraID
- jira_adapter_test.go:61: Failed to create story: failed to create story with status 400: {"errorMessages":[],"errors":{"issuetype":"The issue type selected is invalid."}}
---- FAIL: TestJiraAdapter_CreateStory_ValidStory_ReturnsNewJiraID (0.31s)
-=== RUN TestJiraAdapter_UpdateStory_ValidStoryWithID_Succeeds
- jira_adapter_test.go:97: Failed to create initial story: failed to create story with status 400: {"errorMessages":[],"errors":{"issuetype":"The issue type selected is invalid."}}
---- FAIL: TestJiraAdapter_UpdateStory_ValidStoryWithID_Succeeds (0.30s)
-FAIL
-FAIL github.com/karolswdev/ticktr/internal/adapters/jira 1.010s
-=== RUN TestTicketService_CalculateFinalFields
---- PASS: TestTicketService_CalculateFinalFields (0.00s)
-PASS
-ok github.com/karolswdev/ticktr/internal/core/services 0.001s
-=== RUN TestParser_RecognizesTicketBlock
---- PASS: TestParser_RecognizesTicketBlock (0.00s)
-=== RUN TestParser_ParsesNestedTasks
---- PASS: TestParser_ParsesNestedTasks (0.00s)
-PASS
-ok github.com/karolswdev/ticktr/internal/parser 0.001s
-FAIL
diff --git a/evidence/phase-2/STORY-3/tc-202-1.txt b/evidence/phase-2/STORY-3/tc-202-1.txt
deleted file mode 100644
index 5cee661..0000000
--- a/evidence/phase-2/STORY-3/tc-202-1.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-=== RUN TestSchemaCmd_GeneratesValidYaml
---- PASS: TestSchemaCmd_GeneratesValidYaml (0.00s)
-PASS
-ok github.com/karolswdev/ticktr/cmd/ticketr (cached)
diff --git a/evidence/phase-2/STORY-4/commit.txt b/evidence/phase-2/STORY-4/commit.txt
deleted file mode 100644
index 6c101a7..0000000
--- a/evidence/phase-2/STORY-4/commit.txt
+++ /dev/null
@@ -1 +0,0 @@
-e179e5ee3ba8722f3ecc1aab8b465ec7a4db35f3
diff --git a/evidence/phase-2/STORY-4/readme-diff.txt b/evidence/phase-2/STORY-4/readme-diff.txt
deleted file mode 100644
index b16b66c..0000000
--- a/evidence/phase-2/STORY-4/readme-diff.txt
+++ /dev/null
@@ -1,29 +0,0 @@
-diff --git a/README.md b/README.md
-index 0337b79..fefe1a3 100644
---- a/README.md
-+++ b/README.md
-@@ -150,6 +150,24 @@ ticketr schema -v
-
- This is especially useful when working with custom fields that vary between JIRA instances.
-
-+### State Management
-+
-+Ticketr automatically tracks changes to prevent redundant updates to JIRA:
-+
-+```bash
-+# The .ticketr.state file is created automatically
-+# It stores SHA256 hashes of ticket content
-+
-+# Only changed tickets are pushed to JIRA
-+ticketr push stories.md # Skips unchanged tickets
-+
-+# The state file contains:
-+# - Ticket ID to content hash mappings
-+# - Automatically updated after each successful push
-+```
-+
-+**Note**: The `.ticketr.state` file should be added to `.gitignore` as it's environment-specific.
-+
- ### Docker Usage
-
- Build and run using Docker:
diff --git a/evidence/phase-2/STORY-4/regression.txt b/evidence/phase-2/STORY-4/regression.txt
deleted file mode 100644
index a23860c..0000000
--- a/evidence/phase-2/STORY-4/regression.txt
+++ /dev/null
@@ -1,60 +0,0 @@
-? github.com/karolswdev/ticktr/internal/core/domain [no test files]
-? github.com/karolswdev/ticktr/internal/core/ports [no test files]
-? github.com/karolswdev/ticktr/internal/state [no test files]
-=== RUN TestCLI_WithForceFlag_OnPartialError_UploadsValidTasks
---- PASS: TestCLI_WithForceFlag_OnPartialError_UploadsValidTasks (0.00s)
-=== RUN TestForcePartialUploadLogic
-=== RUN TestForcePartialUploadLogic/Force_flag_with_errors_-_should_not_exit_with_error
-=== RUN TestForcePartialUploadLogic/No_force_flag_with_errors_-_should_exit_with_error
-=== RUN TestForcePartialUploadLogic/Force_flag_without_errors_-_should_not_exit_with_error
-=== RUN TestForcePartialUploadLogic/No_force_flag_without_errors_-_should_not_exit_with_error
---- PASS: TestForcePartialUploadLogic (0.00s)
- --- PASS: TestForcePartialUploadLogic/Force_flag_with_errors_-_should_not_exit_with_error (0.00s)
- --- PASS: TestForcePartialUploadLogic/No_force_flag_with_errors_-_should_exit_with_error (0.00s)
- --- PASS: TestForcePartialUploadLogic/Force_flag_without_errors_-_should_not_exit_with_error (0.00s)
- --- PASS: TestForcePartialUploadLogic/No_force_flag_without_errors_-_should_not_exit_with_error (0.00s)
-=== RUN TestVerboseFlagOutput
---- PASS: TestVerboseFlagOutput (0.00s)
-=== RUN TestCli_ReadsConfigAndDefaults
---- PASS: TestCli_ReadsConfigAndDefaults (0.00s)
-=== RUN TestSchemaCmd_GeneratesValidYaml
---- PASS: TestSchemaCmd_GeneratesValidYaml (0.00s)
-PASS
-ok github.com/karolswdev/ticktr/cmd/ticketr 0.003s
-=== RUN TestParser_ParseInput_ValidFile_ReturnsCorrectStoryCount
---- PASS: TestParser_ParseInput_ValidFile_ReturnsCorrectStoryCount (0.00s)
-=== RUN TestParser_ParseInput_TaskWithDetails_CorrectlyPopulatesTaskFields
---- PASS: TestParser_ParseInput_TaskWithDetails_CorrectlyPopulatesTaskFields (0.00s)
-=== RUN TestParser_ParseInput_WithAndWithoutJiraKeys_CorrectlyPopulatesIDs
---- PASS: TestParser_ParseInput_WithAndWithoutJiraKeys_CorrectlyPopulatesIDs (0.00s)
-=== RUN TestParser_ParseInput_MalformedStoryHeading_ReturnsErrorAndNoStories
---- PASS: TestParser_ParseInput_MalformedStoryHeading_ReturnsErrorAndNoStories (0.00s)
-PASS
-ok github.com/karolswdev/ticktr/internal/adapters/filesystem 0.002s
-=== RUN TestJiraAdapter_CreateTicket_DynamicPayload
---- PASS: TestJiraAdapter_CreateTicket_DynamicPayload (0.00s)
-=== RUN TestJiraAdapter_NewClient_WithEnvVars_AuthenticatesSuccessfully
---- PASS: TestJiraAdapter_NewClient_WithEnvVars_AuthenticatesSuccessfully (0.38s)
-=== RUN TestJiraAdapter_CreateStory_ValidStory_ReturnsNewJiraID
- jira_adapter_test.go:61: Failed to create story: failed to create story with status 400: {"errorMessages":[],"errors":{"issuetype":"The issue type selected is invalid."}}
---- FAIL: TestJiraAdapter_CreateStory_ValidStory_ReturnsNewJiraID (0.40s)
-=== RUN TestJiraAdapter_UpdateStory_ValidStoryWithID_Succeeds
- jira_adapter_test.go:97: Failed to create initial story: failed to create story with status 400: {"errorMessages":[],"errors":{"issuetype":"The issue type selected is invalid."}}
---- FAIL: TestJiraAdapter_UpdateStory_ValidStoryWithID_Succeeds (0.30s)
-FAIL
-FAIL github.com/karolswdev/ticktr/internal/adapters/jira 1.081s
-=== RUN TestPushService_SkipsUnchangedTickets
-2025/08/27 18:36:15 Skipping unchanged ticket 'Test Ticket 1' (TICKET-1)
-2025/08/27 18:36:15 Updated ticket 'Test Ticket 2' with Jira ID: TICKET-2
---- PASS: TestPushService_SkipsUnchangedTickets (0.00s)
-=== RUN TestTicketService_CalculateFinalFields
---- PASS: TestTicketService_CalculateFinalFields (0.00s)
-PASS
-ok github.com/karolswdev/ticktr/internal/core/services 0.002s
-=== RUN TestParser_RecognizesTicketBlock
---- PASS: TestParser_RecognizesTicketBlock (0.00s)
-=== RUN TestParser_ParsesNestedTasks
---- PASS: TestParser_ParsesNestedTasks (0.00s)
-PASS
-ok github.com/karolswdev/ticktr/internal/parser 0.002s
-FAIL
diff --git a/evidence/phase-2/STORY-4/tc-203-1.txt b/evidence/phase-2/STORY-4/tc-203-1.txt
deleted file mode 100644
index 4870f16..0000000
--- a/evidence/phase-2/STORY-4/tc-203-1.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-=== RUN TestJiraAdapter_CreateTicket_DynamicPayload
---- PASS: TestJiraAdapter_CreateTicket_DynamicPayload (0.00s)
-PASS
-ok github.com/karolswdev/ticktr/internal/adapters/jira 0.002s
diff --git a/evidence/phase-2/STORY-4/tc-204-1.txt b/evidence/phase-2/STORY-4/tc-204-1.txt
deleted file mode 100644
index a100093..0000000
--- a/evidence/phase-2/STORY-4/tc-204-1.txt
+++ /dev/null
@@ -1,6 +0,0 @@
-=== RUN TestPushService_SkipsUnchangedTickets
-2025/08/27 18:32:13 Skipping unchanged ticket 'Test Ticket 1' (TICKET-1)
-2025/08/27 18:32:13 Updated ticket 'Test Ticket 2' with Jira ID: TICKET-2
---- PASS: TestPushService_SkipsUnchangedTickets (0.00s)
-PASS
-ok github.com/karolswdev/ticktr/internal/core/services 0.002s
diff --git a/evidence/phase-2/phase-regression.txt b/evidence/phase-2/phase-regression.txt
deleted file mode 100644
index fad65c7..0000000
--- a/evidence/phase-2/phase-regression.txt
+++ /dev/null
@@ -1,60 +0,0 @@
-? github.com/karolswdev/ticktr/internal/core/domain [no test files]
-? github.com/karolswdev/ticktr/internal/core/ports [no test files]
-? github.com/karolswdev/ticktr/internal/state [no test files]
-=== RUN TestCLI_WithForceFlag_OnPartialError_UploadsValidTasks
---- PASS: TestCLI_WithForceFlag_OnPartialError_UploadsValidTasks (0.00s)
-=== RUN TestForcePartialUploadLogic
-=== RUN TestForcePartialUploadLogic/Force_flag_with_errors_-_should_not_exit_with_error
-=== RUN TestForcePartialUploadLogic/No_force_flag_with_errors_-_should_exit_with_error
-=== RUN TestForcePartialUploadLogic/Force_flag_without_errors_-_should_not_exit_with_error
-=== RUN TestForcePartialUploadLogic/No_force_flag_without_errors_-_should_not_exit_with_error
---- PASS: TestForcePartialUploadLogic (0.00s)
- --- PASS: TestForcePartialUploadLogic/Force_flag_with_errors_-_should_not_exit_with_error (0.00s)
- --- PASS: TestForcePartialUploadLogic/No_force_flag_with_errors_-_should_exit_with_error (0.00s)
- --- PASS: TestForcePartialUploadLogic/Force_flag_without_errors_-_should_not_exit_with_error (0.00s)
- --- PASS: TestForcePartialUploadLogic/No_force_flag_without_errors_-_should_not_exit_with_error (0.00s)
-=== RUN TestVerboseFlagOutput
---- PASS: TestVerboseFlagOutput (0.00s)
-=== RUN TestCli_ReadsConfigAndDefaults
---- PASS: TestCli_ReadsConfigAndDefaults (0.00s)
-=== RUN TestSchemaCmd_GeneratesValidYaml
---- PASS: TestSchemaCmd_GeneratesValidYaml (0.00s)
-PASS
-ok github.com/karolswdev/ticktr/cmd/ticketr 0.005s
-=== RUN TestParser_ParseInput_ValidFile_ReturnsCorrectStoryCount
---- PASS: TestParser_ParseInput_ValidFile_ReturnsCorrectStoryCount (0.00s)
-=== RUN TestParser_ParseInput_TaskWithDetails_CorrectlyPopulatesTaskFields
---- PASS: TestParser_ParseInput_TaskWithDetails_CorrectlyPopulatesTaskFields (0.00s)
-=== RUN TestParser_ParseInput_WithAndWithoutJiraKeys_CorrectlyPopulatesIDs
---- PASS: TestParser_ParseInput_WithAndWithoutJiraKeys_CorrectlyPopulatesIDs (0.00s)
-=== RUN TestParser_ParseInput_MalformedStoryHeading_ReturnsErrorAndNoStories
---- PASS: TestParser_ParseInput_MalformedStoryHeading_ReturnsErrorAndNoStories (0.00s)
-PASS
-ok github.com/karolswdev/ticktr/internal/adapters/filesystem 0.003s
-=== RUN TestJiraAdapter_CreateTicket_DynamicPayload
---- PASS: TestJiraAdapter_CreateTicket_DynamicPayload (0.00s)
-=== RUN TestJiraAdapter_NewClient_WithEnvVars_AuthenticatesSuccessfully
---- PASS: TestJiraAdapter_NewClient_WithEnvVars_AuthenticatesSuccessfully (0.24s)
-=== RUN TestJiraAdapter_CreateStory_ValidStory_ReturnsNewJiraID
- jira_adapter_test.go:61: Failed to create story: failed to create story with status 400: {"errorMessages":[],"errors":{"issuetype":"The issue type selected is invalid."}}
---- FAIL: TestJiraAdapter_CreateStory_ValidStory_ReturnsNewJiraID (0.31s)
-=== RUN TestJiraAdapter_UpdateStory_ValidStoryWithID_Succeeds
- jira_adapter_test.go:97: Failed to create initial story: failed to create story with status 400: {"errorMessages":[],"errors":{"issuetype":"The issue type selected is invalid."}}
---- FAIL: TestJiraAdapter_UpdateStory_ValidStoryWithID_Succeeds (0.26s)
-FAIL
-FAIL github.com/karolswdev/ticktr/internal/adapters/jira 0.805s
-=== RUN TestPushService_SkipsUnchangedTickets
-2025/08/27 18:38:25 Skipping unchanged ticket 'Test Ticket 1' (TICKET-1)
-2025/08/27 18:38:25 Updated ticket 'Test Ticket 2' with Jira ID: TICKET-2
---- PASS: TestPushService_SkipsUnchangedTickets (0.00s)
-=== RUN TestTicketService_CalculateFinalFields
---- PASS: TestTicketService_CalculateFinalFields (0.00s)
-PASS
-ok github.com/karolswdev/ticktr/internal/core/services 0.003s
-=== RUN TestParser_RecognizesTicketBlock
---- PASS: TestParser_RecognizesTicketBlock (0.00s)
-=== RUN TestParser_ParsesNestedTasks
---- PASS: TestParser_ParsesNestedTasks (0.00s)
-PASS
-ok github.com/karolswdev/ticktr/internal/parser 0.002s
-FAIL
diff --git a/examples/README.md b/examples/README.md
index 8dd0ff1..a54c7f9 100644
--- a/examples/README.md
+++ b/examples/README.md
@@ -73,14 +73,8 @@ Edit the file to match your specific requirements:
- Add tasks or subtasks as needed
### 3. Validate the Ticket
-```bash
-ticketr validate tickets/PROJ-123.md
-```
-
-### 4. Push to Jira
-```bash
-ticketr push tickets/PROJ-123.md
-```
+- Validate with `ticketr push --dry-run`
+- Push with `ticketr push tickets/PROJ-123.md`
## Template Customization Guidelines
@@ -110,9 +104,8 @@ Customize based on your needs:
## Schema Reference
For complete schema specification, see:
-- **REQUIREMENTS-v2.md** - PROD-201 section
+- **docs/development/REQUIREMENTS.md** - Schema requirements
- **README.md** - Quick Start and Templates sections
-- **docs/migration-guide.md** - Migration from legacy format
## Creating Custom Templates
@@ -120,7 +113,7 @@ To create your own templates:
1. Start with an existing template
2. Add/remove fields based on your workflow
-3. Test with `ticketr validate`
+3. Test with `ticketr push --dry-run`
4. Save in your project's templates directory
5. Share with your team
@@ -152,19 +145,11 @@ To create your own templates:
- Version: [e.g., v1.2.3]
```
-## Legacy Format Notice
-
-Important: These templates use the canonical `# TICKET:` schema introduced in v2.0. If you have legacy files using `# STORY:` format, see the migration guide:
+## Format Reminder
-```bash
-ticketr help migrate
-# or
-cat docs/migration-guide.md
-```
+Ticketr 1.x requires `# TICKET:` headings. Files created before the 1.0 release that still use `# STORY:` must be updated manually before use.
## Additional Resources
- **CLI Help:** `ticketr help`
-- **Validation:** `ticketr validate --help`
-- **Migration:** `ticketr migrate --help`
- **Push/Pull:** `ticketr push --help`, `ticketr pull --help`
diff --git a/examples/pull-with-subtasks-example.md b/examples/pull-with-subtasks-example.md
index cf0cdaf..657ab25 100644
--- a/examples/pull-with-subtasks-example.md
+++ b/examples/pull-with-subtasks-example.md
@@ -200,4 +200,4 @@ If subtasks cannot be fetched (e.g., permissions), parent tickets are still retu
- [README.md - Pull Command](../README.md#pull-command)
- [README.md - Field Inheritance](../README.md#field-inheritance)
-- [REQUIREMENTS-v2.md - PROD-010](../REQUIREMENTS-v2.md#prod-010)
+- [Requirements - PROD-010](../docs/development/REQUIREMENTS.md#prod-010)
diff --git a/internal/core/services/ticket_service_test.go b/internal/core/services/ticket_service_test.go
index a95267c..ccb59ee 100644
--- a/internal/core/services/ticket_service_test.go
+++ b/internal/core/services/ticket_service_test.go
@@ -9,13 +9,13 @@ import (
"github.com/karolswdev/ticktr/internal/core/domain"
)
-// Test Case TC-301.1: TestTicketService_RejectsLegacyStoryFormat
-func TestTicketService_RejectsLegacyStoryFormat(t *testing.T) {
- // Arrange: Create a Markdown file containing the old # STORY: format
+// Test Case TC-301.1: TestTicketService_RejectsStoryHeading
+func TestTicketService_RejectsStoryHeading(t *testing.T) {
+ // Arrange: Create a Markdown file containing the old # STORY: heading
tmpDir := t.TempDir()
- testFile := filepath.Join(tmpDir, "legacy_story.md")
+ testFile := filepath.Join(tmpDir, "story_heading.md")
- legacyContent := `# STORY: Old Format Story
+ storyContent := `# STORY: Old Format Story
## Description
This uses the old format
@@ -26,14 +26,14 @@ This uses the old format
## Tasks
- Old task format`
- err := os.WriteFile(testFile, []byte(legacyContent), 0644)
+ err := os.WriteFile(testFile, []byte(storyContent), 0644)
if err != nil {
t.Fatalf("Failed to create test file: %v", err)
}
- // Create mock repository that returns error for legacy format
- mockRepo := &MockLegacyRepository{}
- mockJira := &MockJiraPortForLegacy{}
+ // Create mock repository that returns error for unsupported format
+ mockRepo := &MockUnsupportedRepository{}
+ mockJira := &MockJiraPortForUnsupported{}
// Act: Pass this file to the ticket_service
service := NewTicketService(mockRepo, mockJira)
@@ -41,7 +41,7 @@ This uses the old format
// Assert: The service returns an error and the ProcessResult indicates zero tickets were processed
if err == nil {
- t.Error("Expected error for legacy STORY format, but got nil")
+ t.Error("Expected error for # STORY heading, but got nil")
}
if result != nil && result.TicketsCreated > 0 {
@@ -49,70 +49,70 @@ This uses the old format
}
if mockJira.createCalled {
- t.Error("JIRA adapter should not be called for legacy format")
+ t.Error("JIRA adapter should not be called for unsupported format")
}
}
-// MockLegacyRepository rejects legacy format
-type MockLegacyRepository struct{}
+// MockUnsupportedRepository rejects files using # STORY headings
+type MockUnsupportedRepository struct{}
-func (m *MockLegacyRepository) GetTickets(filepath string) ([]domain.Ticket, error) {
+func (m *MockUnsupportedRepository) GetTickets(filepath string) ([]domain.Ticket, error) {
// Read the file to check format
content, err := os.ReadFile(filepath)
if err != nil {
return nil, err
}
- // Check for legacy STORY format
+ // Check for unsupported STORY heading
contentStr := string(content)
if len(contentStr) >= 8 && contentStr[:8] == "# STORY:" {
- return nil, fmt.Errorf("legacy STORY format is no longer supported, use # TICKET: instead")
+ return nil, fmt.Errorf("'# STORY:' format is not supported; use '# TICKET:' instead")
}
return []domain.Ticket{}, nil
}
-func (m *MockLegacyRepository) SaveTickets(filepath string, tickets []domain.Ticket) error {
+func (m *MockUnsupportedRepository) SaveTickets(filepath string, tickets []domain.Ticket) error {
return nil
}
-// MockJiraPortForLegacy tracks if methods were called
-type MockJiraPortForLegacy struct {
+// MockJiraPortForUnsupported tracks if methods were called
+type MockJiraPortForUnsupported struct {
createCalled bool
updateCalled bool
}
-func (m *MockJiraPortForLegacy) Authenticate() error {
+func (m *MockJiraPortForUnsupported) Authenticate() error {
return nil
}
-func (m *MockJiraPortForLegacy) CreateTask(task domain.Task, parentID string) (string, error) {
+func (m *MockJiraPortForUnsupported) CreateTask(task domain.Task, parentID string) (string, error) {
return "TASK-123", nil
}
-func (m *MockJiraPortForLegacy) UpdateTask(task domain.Task) error {
+func (m *MockJiraPortForUnsupported) UpdateTask(task domain.Task) error {
return nil
}
-func (m *MockJiraPortForLegacy) GetProjectIssueTypes() (map[string][]string, error) {
+func (m *MockJiraPortForUnsupported) GetProjectIssueTypes() (map[string][]string, error) {
return nil, nil
}
-func (m *MockJiraPortForLegacy) GetIssueTypeFields(issueTypeName string) (map[string]interface{}, error) {
+func (m *MockJiraPortForUnsupported) GetIssueTypeFields(issueTypeName string) (map[string]interface{}, error) {
return nil, nil
}
-func (m *MockJiraPortForLegacy) CreateTicket(ticket domain.Ticket) (string, error) {
+func (m *MockJiraPortForUnsupported) CreateTicket(ticket domain.Ticket) (string, error) {
m.createCalled = true
return "TICKET-123", nil
}
-func (m *MockJiraPortForLegacy) UpdateTicket(ticket domain.Ticket) error {
+func (m *MockJiraPortForUnsupported) UpdateTicket(ticket domain.Ticket) error {
m.updateCalled = true
return nil
}
-func (m *MockJiraPortForLegacy) SearchTickets(projectKey string, jql string) ([]domain.Ticket, error) {
+func (m *MockJiraPortForUnsupported) SearchTickets(projectKey string, jql string) ([]domain.Ticket, error) {
return []domain.Ticket{}, nil
}
diff --git a/internal/migration/migrator.go b/internal/migration/migrator.go
deleted file mode 100644
index af616e7..0000000
--- a/internal/migration/migrator.go
+++ /dev/null
@@ -1,65 +0,0 @@
-package migration
-
-import (
- "fmt"
- "os"
- "strings"
-)
-
-// Migrator handles conversion from legacy # STORY: to # TICKET: format
-type Migrator struct {
- DryRun bool
-}
-
-// MigrateFile converts a single file from STORY to TICKET format
-// Returns: (modified content, changed bool, error)
-func (m *Migrator) MigrateFile(filepath string) (string, bool, error) {
- // Read file content
- content, err := os.ReadFile(filepath)
- if err != nil {
- return "", false, fmt.Errorf("failed to read file: %w", err)
- }
-
- originalContent := string(content)
-
- // Use strings.ReplaceAll to replace # STORY: with # TICKET:
- modifiedContent := strings.ReplaceAll(originalContent, "# STORY:", "# TICKET:")
-
- // Check if any changes were made
- changed := modifiedContent != originalContent
-
- return modifiedContent, changed, nil
-}
-
-// PreviewDiff shows what would change (for dry-run mode)
-func (m *Migrator) PreviewDiff(filepath string, oldContent, newContent string) string {
- var result strings.Builder
-
- result.WriteString(fmt.Sprintf("Preview of changes for: %s\n", filepath))
-
- // Split into lines and show changes
- oldLines := strings.Split(oldContent, "\n")
- newLines := strings.Split(newContent, "\n")
-
- changeCount := 0
- for i := 0; i < len(oldLines) && i < len(newLines); i++ {
- if oldLines[i] != newLines[i] {
- changeCount++
- result.WriteString(fmt.Sprintf(" Line %d: %s -> %s\n", i+1, oldLines[i], newLines[i]))
- }
- }
-
- result.WriteString(fmt.Sprintf("\n%d change(s) would be made. Use --write to apply.\n", changeCount))
-
- return result.String()
-}
-
-// WriteMigration writes the migrated content to file
-func (m *Migrator) WriteMigration(filepath string, content string) error {
- // Write content to file with proper permissions (0644 = rw-r--r--)
- err := os.WriteFile(filepath, []byte(content), 0644)
- if err != nil {
- return fmt.Errorf("failed to write file: %w", err)
- }
- return nil
-}
diff --git a/internal/migration/migrator_test.go b/internal/migration/migrator_test.go
deleted file mode 100644
index 42352af..0000000
--- a/internal/migration/migrator_test.go
+++ /dev/null
@@ -1,227 +0,0 @@
-package migration
-
-import (
- "os"
- "path/filepath"
- "strings"
- "testing"
-)
-
-func TestMigrator_ConvertsSingleStory(t *testing.T) {
- migrator := &Migrator{DryRun: true}
-
- // Use testdata/legacy_story/simple_story.md
- testFile := "../../testdata/legacy_story/simple_story.md"
-
- content, changed, err := migrator.MigrateFile(testFile)
- if err != nil {
- t.Fatalf("MigrateFile failed: %v", err)
- }
-
- // Verify "# STORY:" becomes "# TICKET:"
- if !strings.Contains(content, "# TICKET:") {
- t.Errorf("Expected migrated content to contain '# TICKET:', got: %s", content)
- }
-
- if strings.Contains(content, "# STORY:") {
- t.Errorf("Expected migrated content to not contain '# STORY:', but it does")
- }
-
- // Verify other content unchanged
- if !strings.Contains(content, "USER-123 Simple user story") {
- t.Errorf("Expected content to preserve ticket title")
- }
-
- if !strings.Contains(content, "As a user, I want to see my profile.") {
- t.Errorf("Expected content to preserve description")
- }
-
- // Verify changed flag is true
- if !changed {
- t.Errorf("Expected changed=true, got false")
- }
-}
-
-func TestMigrator_ConvertsMultipleStories(t *testing.T) {
- migrator := &Migrator{DryRun: true}
-
- // Use testdata/legacy_story/multiple_stories.md
- testFile := "../../testdata/legacy_story/multiple_stories.md"
-
- content, changed, err := migrator.MigrateFile(testFile)
- if err != nil {
- t.Fatalf("MigrateFile failed: %v", err)
- }
-
- // Verify all occurrences converted
- storyCount := strings.Count(content, "# STORY:")
- if storyCount != 0 {
- t.Errorf("Expected 0 occurrences of '# STORY:', found %d", storyCount)
- }
-
- ticketCount := strings.Count(content, "# TICKET:")
- if ticketCount != 2 {
- t.Errorf("Expected 2 occurrences of '# TICKET:', found %d", ticketCount)
- }
-
- if !changed {
- t.Errorf("Expected changed=true, got false")
- }
-}
-
-func TestMigrator_PreservesFormatting(t *testing.T) {
- migrator := &Migrator{DryRun: true}
-
- testFile := "../../testdata/legacy_story/simple_story.md"
-
- // Read original content
- originalBytes, err := os.ReadFile(testFile)
- if err != nil {
- t.Fatalf("Failed to read original file: %v", err)
- }
- original := string(originalBytes)
-
- content, _, err := migrator.MigrateFile(testFile)
- if err != nil {
- t.Fatalf("MigrateFile failed: %v", err)
- }
-
- // Verify whitespace, indentation preserved
- originalLines := strings.Split(original, "\n")
- contentLines := strings.Split(content, "\n")
-
- if len(originalLines) != len(contentLines) {
- t.Errorf("Expected same number of lines: original=%d, migrated=%d", len(originalLines), len(contentLines))
- }
-
- // Verify only header line changed
- changedLines := 0
- for i := 0; i < len(originalLines) && i < len(contentLines); i++ {
- if originalLines[i] != contentLines[i] {
- changedLines++
- // The changed line should be the conversion from STORY to TICKET
- if !strings.Contains(originalLines[i], "# STORY:") || !strings.Contains(contentLines[i], "# TICKET:") {
- t.Errorf("Unexpected line change at line %d: '%s' -> '%s'", i+1, originalLines[i], contentLines[i])
- }
- }
- }
-
- if changedLines != 1 {
- t.Errorf("Expected exactly 1 line to change, got %d", changedLines)
- }
-}
-
-func TestMigrator_HandlesNoChangesNeeded(t *testing.T) {
- migrator := &Migrator{DryRun: true}
-
- // Test with file already using # TICKET:
- testFile := "../../testdata/ticket_simple.md"
-
- content, changed, err := migrator.MigrateFile(testFile)
- if err != nil {
- t.Fatalf("MigrateFile failed: %v", err)
- }
-
- // Verify changed=false returned
- if changed {
- t.Errorf("Expected changed=false for file already using # TICKET:, got true")
- }
-
- // Verify content unchanged
- originalBytes, _ := os.ReadFile(testFile)
- original := string(originalBytes)
-
- if content != original {
- t.Errorf("Expected content to remain unchanged")
- }
-}
-
-func TestMigrator_HandlesFileErrors(t *testing.T) {
- migrator := &Migrator{DryRun: true}
-
- // Test non-existent file
- _, _, err := migrator.MigrateFile("/nonexistent/path/file.md")
- if err == nil {
- t.Errorf("Expected error for non-existent file, got nil")
- }
-
- // Verify appropriate error returned
- if !strings.Contains(err.Error(), "failed to read file") {
- t.Errorf("Expected error message to contain 'failed to read file', got: %s", err.Error())
- }
-}
-
-func TestMigrator_WriteMigration(t *testing.T) {
- migrator := &Migrator{DryRun: false}
-
- // Create a temporary file for testing
- tmpDir := t.TempDir()
- testFile := filepath.Join(tmpDir, "test_migration.md")
-
- // Write initial content with # STORY:
- initialContent := "# STORY: TEST-001 Test story\n\n## Description\nTest content\n"
- err := os.WriteFile(testFile, []byte(initialContent), 0644)
- if err != nil {
- t.Fatalf("Failed to create test file: %v", err)
- }
-
- // Perform migration
- content, changed, err := migrator.MigrateFile(testFile)
- if err != nil {
- t.Fatalf("MigrateFile failed: %v", err)
- }
-
- if !changed {
- t.Fatalf("Expected changes, got none")
- }
-
- // Write the migration
- err = migrator.WriteMigration(testFile, content)
- if err != nil {
- t.Fatalf("WriteMigration failed: %v", err)
- }
-
- // Verify file was written correctly
- writtenBytes, err := os.ReadFile(testFile)
- if err != nil {
- t.Fatalf("Failed to read written file: %v", err)
- }
-
- written := string(writtenBytes)
- if !strings.Contains(written, "# TICKET:") {
- t.Errorf("Expected written file to contain '# TICKET:'")
- }
-
- if strings.Contains(written, "# STORY:") {
- t.Errorf("Expected written file to not contain '# STORY:'")
- }
-}
-
-func TestMigrator_PreviewDiff(t *testing.T) {
- migrator := &Migrator{DryRun: true}
-
- oldContent := "# STORY: TEST-001 Test\n\nContent here\n"
- newContent := "# TICKET: TEST-001 Test\n\nContent here\n"
-
- preview := migrator.PreviewDiff("test.md", oldContent, newContent)
-
- // Verify preview contains filename
- if !strings.Contains(preview, "test.md") {
- t.Errorf("Expected preview to contain filename")
- }
-
- // Verify preview shows line numbers
- if !strings.Contains(preview, "Line 1") {
- t.Errorf("Expected preview to show line numbers")
- }
-
- // Verify preview shows the change
- if !strings.Contains(preview, "# STORY:") || !strings.Contains(preview, "# TICKET:") {
- t.Errorf("Expected preview to show both old and new content")
- }
-
- // Verify preview mentions --write flag
- if !strings.Contains(preview, "--write") {
- t.Errorf("Expected preview to mention --write flag")
- }
-}
diff --git a/internal/parser/parser.go b/internal/parser/parser.go
index 5225e96..d917685 100644
--- a/internal/parser/parser.go
+++ b/internal/parser/parser.go
@@ -30,10 +30,10 @@ func (p *Parser) Parse(filePath string) ([]domain.Ticket, error) {
lineNum++
line := scanner.Text()
- // Check for legacy # STORY: format
+ // Check for unsupported # STORY: format
if strings.HasPrefix(strings.TrimSpace(line), "# STORY:") {
//lint:ignore ST1005 Capitalized for clarity in user-facing error message
- return nil, fmt.Errorf("Legacy '# STORY:' format detected at line %d - please migrate to '# TICKET:' format: see REQUIREMENTS-v2.md (PROD-201) or use 'ticketr migrate ' command", lineNum)
+ return nil, fmt.Errorf("'# STORY:' format detected at line %d - ticketr requires '# TICKET:' headings.", lineNum)
}
lines = append(lines, line)
diff --git a/internal/parser/parser_test.go b/internal/parser/parser_test.go
index a6d09e3..0ba44a0 100644
--- a/internal/parser/parser_test.go
+++ b/internal/parser/parser_test.go
@@ -97,25 +97,25 @@ func TestParser_ParsesNestedTasks(t *testing.T) {
}
}
-func TestParser_RejectsLegacyStoryFormat(t *testing.T) {
+func TestParser_RejectsStoryHeading(t *testing.T) {
parser := New()
// Test that parser rejects # STORY: format
- tickets, err := parser.Parse("../../testdata/legacy_story/simple_story.md")
+ tickets, err := parser.Parse("../../testdata/unsupported_story/simple_story.md")
// Should return an error
if err == nil {
- t.Fatal("Expected error for legacy # STORY: format, but got nil")
+ t.Fatal("Expected error for # STORY: heading, but got nil")
}
- // Verify error message contains "Legacy" and "STORY"
+ // Verify error message contains guidance mentioning STORY and TICKET
errMsg := err.Error()
- if !contains(errMsg, "Legacy") {
- t.Errorf("Expected error message to contain 'Legacy', got: %s", errMsg)
- }
if !contains(errMsg, "STORY") {
t.Errorf("Expected error message to contain 'STORY', got: %s", errMsg)
}
+ if !contains(errMsg, "TICKET") {
+ t.Errorf("Expected error message to mention 'TICKET', got: %s", errMsg)
+ }
// Verify tickets are empty since parsing failed
if len(tickets) > 0 {
@@ -123,42 +123,35 @@ func TestParser_RejectsLegacyStoryFormat(t *testing.T) {
}
}
-func TestParser_ErrorMessageIncludesMigrationGuidance(t *testing.T) {
+func TestParser_ErrorMessageGuidesUser(t *testing.T) {
parser := New()
// Test that error message is helpful
- _, err := parser.Parse("../../testdata/legacy_story/simple_story.md")
+ _, err := parser.Parse("../../testdata/unsupported_story/simple_story.md")
if err == nil {
- t.Fatal("Expected error for legacy # STORY: format, but got nil")
+ t.Fatal("Expected error for # STORY: heading, but got nil")
}
errMsg := err.Error()
- // Verify error contains "migrate" command reference
- if !contains(errMsg, "migrate") {
- t.Errorf("Expected error message to contain 'migrate', got: %s", errMsg)
+ // Verify error includes guidance to use # TICKET and line number
+ if !contains(errMsg, "TICKET") {
+ t.Errorf("Expected error message to mention 'TICKET', got: %s", errMsg)
}
-
- // Verify error contains "REQUIREMENTS-v2.md" reference
- if !contains(errMsg, "REQUIREMENTS-v2.md") {
- t.Errorf("Expected error message to contain 'REQUIREMENTS-v2.md', got: %s", errMsg)
- }
-
- // Verify error includes line number
if !contains(errMsg, "line") {
t.Errorf("Expected error message to contain 'line', got: %s", errMsg)
}
}
-func TestParser_RejectsMultipleLegacyStories(t *testing.T) {
+func TestParser_RejectsMultipleStoryHeadings(t *testing.T) {
parser := New()
- // Test with testdata/legacy_story/multiple_stories.md
- _, err := parser.Parse("../../testdata/legacy_story/multiple_stories.md")
+ // Test with unsupported story format fixture
+ _, err := parser.Parse("../../testdata/unsupported_story/multiple_stories.md")
if err == nil {
- t.Fatal("Expected error for legacy # STORY: format with multiple stories, but got nil")
+ t.Fatal("Expected error for # STORY: heading with multiple stories, but got nil")
}
// Verify parser catches first occurrence (should mention line 1)
diff --git a/internal/state/manager_test.go b/internal/state/manager_test.go
index cae0f4d..16dea97 100644
--- a/internal/state/manager_test.go
+++ b/internal/state/manager_test.go
@@ -148,9 +148,9 @@ func TestStateManager_BackwardCompatibility(t *testing.T) {
sm := NewStateManager(stateFile)
err = sm.Load()
// We expect this to fail with the new structure, which is acceptable
- // as we're making a breaking change in v2.0
+ // because the 1.0 release changed the state format
if err == nil {
- t.Error("Expected error when loading old format, as v2.0 is a breaking change")
+ t.Error("Expected error when loading old format, as the 1.0 release changed state layout")
}
}
diff --git a/testdata/legacy_story/story_with_tasks.md b/testdata/legacy_story/story_with_tasks.md
deleted file mode 100644
index 3e7741f..0000000
--- a/testdata/legacy_story/story_with_tasks.md
+++ /dev/null
@@ -1,14 +0,0 @@
-# STORY: USER-456 Story with tasks
-
-## Description
-As a developer, I need task hierarchy support.
-
-## Tasks
-- [TASK-001] Implement parser
- ## Fields
- Status: In Progress
- Assignee: dev@example.com
-
-- [TASK-002] Add tests
- ## Fields
- Status: Todo
diff --git a/testdata/task_with_details.md b/testdata/task_with_details.md
deleted file mode 100644
index 6925d4f..0000000
--- a/testdata/task_with_details.md
+++ /dev/null
@@ -1,16 +0,0 @@
-# TICKET: Task with Details
-## Description
-Story description here.
-
-## Fields
-Type: Story
-Project: PROJ
-
-## Tasks
-- Implement feature
- ## Description
- This is a detailed description of the task that needs to be implemented
-
- ## Acceptance Criteria
- - The feature should work correctly
- - All tests should pass
\ No newline at end of file
diff --git a/testdata/two_tickets.md b/testdata/two_tickets.md
deleted file mode 100644
index fd2c5d5..0000000
--- a/testdata/two_tickets.md
+++ /dev/null
@@ -1,32 +0,0 @@
-# TICKET: User Authentication
-## Description
-As a user, I want to be able to log in to the system.
-
-## Fields
-Type: Story
-Project: PROJ
-
-## Acceptance Criteria
-- User can enter username and password
-- System validates credentials
-
-## Tasks
-- Implement login form
-- Add validation logic
-
-# TICKET: User Profile Management
-
-## Description
-As a user, I want to manage my profile information.
-
-## Fields
-Type: Story
-Project: PROJ
-
-## Acceptance Criteria
-- User can view profile
-- User can edit profile
-
-## Tasks
-- Create profile page
-- Add edit functionality
\ No newline at end of file
diff --git a/testdata/legacy_story/multiple_stories.md b/testdata/unsupported_story/multiple_stories.md
similarity index 100%
rename from testdata/legacy_story/multiple_stories.md
rename to testdata/unsupported_story/multiple_stories.md
diff --git a/testdata/legacy_story/simple_story.md b/testdata/unsupported_story/simple_story.md
similarity index 100%
rename from testdata/legacy_story/simple_story.md
rename to testdata/unsupported_story/simple_story.md
diff --git a/tests/smoke/README.md b/tests/smoke/README.md
index c144f59..cf3a868 100644
--- a/tests/smoke/README.md
+++ b/tests/smoke/README.md
@@ -54,16 +54,16 @@ The script will output colored test results:
Example:
```
======================================
-TEST 1: Migrate Legacy Files
+TEST 1: Push Dry-Run Validation
======================================
-PASS: Migrate detected legacy file STORY-123.md
-PASS: Migration preserved ticket content
+PASS: Push dry-run executed without errors
+PASS: Dry-run did not modify source file
======================================
SMOKE TEST SUMMARY
======================================
-Tests Run: 15
-Tests Passed: 15
+Tests Run: 12
+Tests Passed: 12
Tests Failed: 0
ALL SMOKE TESTS PASSED
@@ -71,22 +71,7 @@ ALL SMOKE TESTS PASSED
## Test Scenarios
-### Test 1: Migrate Legacy Files
-**Purpose**: Verify that `ticketr migrate` correctly identifies and migrates legacy markdown files with `# STORY` prefixes.
-
-**What it tests**:
-- Legacy file detection in dry-run mode
-- Actual migration execution
-- Content preservation after migration
-
-**Expected behavior**:
-- Command exits successfully
-- Legacy files are detected
-- File content remains intact
-
----
-
-### Test 2: Push Dry-Run Validation
+### Test 1: Push Dry-Run Validation
**Purpose**: Ensure `ticketr push --dry-run` validates tickets without making actual changes.
**What it tests**:
@@ -101,7 +86,7 @@ ALL SMOKE TESTS PASSED
---
-### Test 3: Pull with Missing File (First-Run)
+### Test 2: Pull with Missing File (First-Run)
**Purpose**: Verify that `ticketr pull` handles first-run scenarios gracefully.
**What it tests**:
@@ -116,7 +101,7 @@ ALL SMOKE TESTS PASSED
---
-### Test 4: State File Creation and Persistence
+### Test 3: State File Creation and Persistence
**Purpose**: Confirm that Ticketr creates and maintains state files correctly.
**What it tests**:
@@ -131,7 +116,7 @@ ALL SMOKE TESTS PASSED
---
-### Test 5: Log File Creation
+### Test 4: Log File Creation
**Purpose**: Verify that execution logs are created in the correct location.
**What it tests**:
@@ -146,7 +131,7 @@ ALL SMOKE TESTS PASSED
---
-### Test 6: Help Command and Basic CLI
+### Test 5: Help Command and Basic CLI
**Purpose**: Ensure basic CLI functionality works.
**What it tests**:
@@ -277,7 +262,7 @@ Currently, the smoke tests do not use environment variables. Future enhancements
## Related Documentation
- [ROADMAP.md](../../ROADMAP.md) - Milestone 11: Quality Gates & Automation
-- [REQUIREMENTS-v2.md](../../REQUIREMENTS-v2.md) - Functional requirements
+- [Requirements](../../docs/development/REQUIREMENTS.md) - Functional requirements
- [CI Workflow](../../.github/workflows/ci.yml) - GitHub Actions integration
## Support
diff --git a/tests/smoke/smoke_test.sh b/tests/smoke/smoke_test.sh
index 570c9f7..392eb75 100755
--- a/tests/smoke/smoke_test.sh
+++ b/tests/smoke/smoke_test.sh
@@ -73,61 +73,14 @@ TEST_ROOT="/tmp/smoke-test-$$"
mkdir -p "$TEST_ROOT"
# ==============================================================================
-# TEST 1: ticketr migrate on legacy files
+# TEST 1: ticketr push dry-run validation
# ==============================================================================
-log_test "1" "Migrate Legacy Files"
+log_test "1" "Push Dry-Run Validation"
TEST_DIR="$TEST_ROOT/test1"
mkdir -p "$TEST_DIR"
cd "$TEST_DIR"
-# Create a legacy markdown file with # STORY prefix
-cat > "STORY-123.md" <<'EOF'
-# STORY-123: User Authentication
-
-## Description
-Implement user authentication for the application.
-
-## Acceptance Criteria
-- User can log in with email and password
-- User can log out
-- Session is maintained across page refreshes
-
-## Status
-In Progress
-EOF
-
-# Run migrate command (dry-run is the default)
-# The migrate command exits without error even if no changes are needed
-if $TICKETR_BIN migrate "STORY-123.md" > /dev/null 2>&1 || [ $? -eq 0 ]; then
- log_pass "Migrate command executed successfully on STORY-123.md"
-else
- log_fail "Migrate command failed"
-fi
-
-# Run actual migration (non-dry-run)
-$TICKETR_BIN migrate "STORY-123.md" --write > /dev/null 2>&1 || true
-
-# Check if migrated file exists
-if [ -f "STORY-123.md" ]; then
- if grep -q "# STORY-123" "STORY-123.md" || grep -q "Key: STORY-123" "STORY-123.md"; then
- log_pass "Migration preserved ticket content"
- else
- log_fail "Migration corrupted ticket content"
- fi
-else
- log_fail "Migrated file not found"
-fi
-
-# ==============================================================================
-# TEST 2: ticketr push dry-run validation
-# ==============================================================================
-log_test "2" "Push Dry-Run Validation"
-
-TEST_DIR="$TEST_ROOT/test2"
-mkdir -p "$TEST_DIR"
-cd "$TEST_DIR"
-
# Create a valid ticket file
cat > "PROJ-456.md" <<'EOF'
---
@@ -157,11 +110,11 @@ else
fi
# ==============================================================================
-# TEST 3: ticketr pull with missing file (first-run scenario)
+# TEST 2: ticketr pull with missing file (first-run scenario)
# ==============================================================================
-log_test "3" "Pull with Missing File (First-Run)"
+log_test "2" "Pull with Missing File (First-Run)"
-TEST_DIR="$TEST_ROOT/test3"
+TEST_DIR="$TEST_ROOT/test2"
mkdir -p "$TEST_DIR"
cd "$TEST_DIR"
@@ -184,11 +137,11 @@ else
fi
# ==============================================================================
-# TEST 4: State file creation and persistence
+# TEST 3: State file creation and persistence
# ==============================================================================
-log_test "4" "State File Creation and Persistence"
+log_test "3" "State File Creation and Persistence"
-TEST_DIR="$TEST_ROOT/test4"
+TEST_DIR="$TEST_ROOT/test3"
mkdir -p "$TEST_DIR"
cd "$TEST_DIR"
@@ -237,11 +190,11 @@ else
fi
# ==============================================================================
-# TEST 5: Log file creation in .ticketr/logs/
+# TEST 4: Log file creation in .ticketr/logs/
# ==============================================================================
-log_test "5" "Log File Creation"
+log_test "4" "Log File Creation"
-TEST_DIR="$TEST_ROOT/test5"
+TEST_DIR="$TEST_ROOT/test4"
mkdir -p "$TEST_DIR"
cd "$TEST_DIR"
@@ -289,11 +242,11 @@ if [ "$LOG_COUNT" -gt 0 ]; then
fi
# ==============================================================================
-# TEST 6: Help command and version info
+# TEST 5: Help command and version info
# ==============================================================================
-log_test "6" "Help Command and Basic CLI"
+log_test "5" "Help Command and Basic CLI"
-TEST_DIR="$TEST_ROOT/test6"
+TEST_DIR="$TEST_ROOT/test5"
mkdir -p "$TEST_DIR"
cd "$TEST_DIR"
@@ -312,11 +265,11 @@ else
fi
# ==============================================================================
-# TEST 7: Concurrent file operations (basic safety check)
+# TEST 6: Concurrent file operations (basic safety check)
# ==============================================================================
-log_test "7" "Concurrent File Operations Safety"
+log_test "6" "Concurrent File Operations Safety"
-TEST_DIR="$TEST_ROOT/test7"
+TEST_DIR="$TEST_ROOT/test6"
mkdir -p "$TEST_DIR"
cd "$TEST_DIR"