Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions docs/core-cli/modes.md
Original file line number Diff line number Diff line change
Expand Up @@ -179,7 +179,7 @@ The `import from-code` command now uses mode-aware routing. You should see mode

```bash
# Test with CI/CD mode (bundle name as positional argument)
hatch run specfact --mode cicd import from-code test-project --repo . --confidence 0.5 --shadow-only
hatch run specfact --mode cicd code import from-code test-project --repo . --confidence 0.5 --shadow-only

# Expected output:
# Mode: CI/CD (direct execution)
Expand All @@ -189,7 +189,7 @@ hatch run specfact --mode cicd import from-code test-project --repo . --confiden

```bash
# Test with CoPilot mode (bundle name as positional argument)
hatch run specfact --mode copilot import from-code test-project --repo . --confidence 0.5 --shadow-only
hatch run specfact --mode copilot code import from-code test-project --repo . --confidence 0.5 --shadow-only

# Expected output:
# Mode: CoPilot (agent routing)
Expand Down Expand Up @@ -249,7 +249,7 @@ hatch run specfact code import my-project --repo . --confidence 0.7

```bash
# Developer wants CI/CD mode even though CoPilot is available (bundle name as positional argument)
hatch run specfact --mode cicd import from-code my-project --repo . --confidence 0.7
hatch run specfact --mode cicd code import from-code my-project --repo . --confidence 0.7

# Expected: Mode: CI/CD (direct execution) - flag overrides auto-detection
```
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ cd /tmp/specfact-integration-tests/example1_vscode
# The AI will prompt for a plan name - suggest: "Payment Processing"

# Alternative: CLI-only mode (bundle name as positional argument)
specfact --no-banner import from-code payment-processing --repo . --output-format yaml
specfact --no-banner code import from-code payment-processing --repo . --output-format yaml

# Step 2: Run enforcement
specfact --no-banner enforce stage --preset balanced
Expand All @@ -95,7 +95,7 @@ specfact --no-banner enforce stage --preset balanced
cd /tmp/specfact-integration-tests/example2_cursor

# Step 1: Import code (bundle name as positional argument)
specfact --no-banner import from-code data-pipeline --repo . --output-format yaml
specfact --no-banner code import from-code data-pipeline --repo . --output-format yaml

# Step 2: Test original (should pass)
specfact --no-banner enforce stage --preset balanced
Expand All @@ -117,7 +117,7 @@ specfact --no-banner plan compare src/pipeline.py src/pipeline_broken.py --fail-
cd /tmp/specfact-integration-tests/example3_github_actions

# Step 1: Import code (bundle name as positional argument)
specfact --no-banner import from-code user-api --repo . --output-format yaml
specfact --no-banner code import from-code user-api --repo . --output-format yaml

# Step 2: Run enforcement
specfact --no-banner enforce stage --preset balanced
Expand All @@ -135,7 +135,7 @@ specfact --no-banner enforce stage --preset balanced
cd /tmp/specfact-integration-tests/example4_precommit

# Step 1: Initial commit (bundle name as positional argument)
specfact --no-banner import from-code order-processor --repo . --output-format yaml
specfact --no-banner code import from-code order-processor --repo . --output-format yaml
git add .
git commit -m "Initial code"

Expand Down Expand Up @@ -220,7 +220,7 @@ for dir in example1_vscode example2_cursor example3_github_actions example4_prec
echo "Testing $dir..."
cd /tmp/specfact-integration-tests/$dir
bundle_name=$(echo "$dir" | sed 's/example[0-9]_//')
specfact --no-banner import from-code "$bundle_name" --repo . --output-format yaml 2>&1
specfact --no-banner code import from-code "$bundle_name" --repo . --output-format yaml 2>&1
specfact --no-banner enforce stage --preset balanced 2>&1
echo "---"
done
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -223,7 +223,7 @@ def process_payment(request):
### Option B: CLI-only (For Integration Testing)

```bash
uvx specfact-cli@latest --no-banner import from-code --repo . --output-format yaml
uvx specfact-cli@latest --no-banner code import from-code --repo . --output-format yaml
```

**Note**: CLI-only mode uses AST-based analysis and may show "0 features" for minimal test cases. This is expected and the plan bundle is still created for manual contract addition.
Expand All @@ -234,17 +234,17 @@ uvx specfact-cli@latest --no-banner import from-code --repo . --output-format ya
- **Repeated runs**: Use `--no-banner` **before** the command to suppress banner output
- **Important**: `--no-banner` is a global parameter and must come **before** the subcommand, not after
- ✅ Correct: `specfact --no-banner enforce stage --preset balanced`
- ✅ Correct: `uvx specfact-cli@latest --no-banner import from-code --repo . --output-format yaml`
- ✅ Correct: `uvx specfact-cli@latest --no-banner code import from-code --repo . --output-format yaml`
- ❌ Wrong: `specfact govern enforce stage --preset balanced --no-banner`
- ❌ Wrong: `uvx specfact-cli@latest import from-code --repo . --output-format yaml --no-banner`
- ❌ Wrong: `uvx specfact-cli@latest code import from-code --repo . --output-format yaml --no-banner`

**Note**: The `import from-code` command analyzes the entire repository/directory, not individual files. It will automatically detect and analyze all Python files in the current directory.
**Note**: The `code import from-code` command analyzes the entire repository/directory, not individual files. It will automatically detect and analyze all Python files in the current directory.

**Important**: These examples are designed for **interactive AI assistant usage** (slash commands in Cursor, VS Code, etc.), not CLI-only execution.

**CLI vs Interactive Mode**:

- **CLI-only** (`uvx specfact-cli@latest import from-code` or `specfact code import`): Uses AST-based analyzer (CI/CD mode)
- **CLI-only** (`uvx specfact-cli@latest code import from-code` or `specfact code import`): Uses AST-based analyzer (CI/CD mode)
- May show "0 features" for minimal test cases
- Limited to AST pattern matching
- Works but may not detect all features in simple examples
Expand Down Expand Up @@ -368,7 +368,7 @@ specfact --no-banner plan review django-example \
- ✅ Stories are present in the plan bundle
- ✅ Acceptance criteria are complete and testable

**Note**: Contracts are **automatically extracted** during `import from-code` by the AST analyzer, but only if function signatures have type hints. For the async bug detection example, detecting "blocking I/O in async context" requires additional analysis (Semgrep async patterns, not just AST contracts).
**Note**: Contracts are **automatically extracted** during `code import from-code` by the AST analyzer, but only if function signatures have type hints. For the async bug detection example, detecting "blocking I/O in async context" requires additional analysis (Semgrep async patterns, not just AST contracts).

#### Step 3.4: Set Up Enforcement Configuration

Expand Down Expand Up @@ -511,7 +511,7 @@ Fix the blocking deviations or adjust enforcement config

**What We've Accomplished**:

1. ✅ Created plan bundle from code (`import from-code`)
1. ✅ Created plan bundle from code (`code import from-code`)
2. ✅ Enriched plan with semantic understanding (added feature and stories)
3. ✅ Reviewed plan and added missing stories via CLI
4. ✅ Configured enforcement (balanced preset)
Expand Down Expand Up @@ -637,7 +637,7 @@ Stories added (4 total):
**Alternative**: CLI-only mode:

```bash
uvx specfact-cli@latest --no-banner import from-code --repo . --output-format yaml
uvx specfact-cli@latest --no-banner code import from-code --repo . --output-format yaml
```

**Note**: Interactive mode creates valid plan bundles with features. CLI-only may show 0 features for minimal test cases. Use `--no-banner` before the command to suppress banner output: `specfact --no-banner <command>`.
Expand Down Expand Up @@ -877,7 +877,7 @@ mv src/pipeline.py src/pipeline_original.py
mv src/pipeline_broken.py src/pipeline.py

# 3. Import broken code to create new plan
specfact --no-banner import from-code pipeline-broken --repo . --output-format yaml
specfact --no-banner code import from-code pipeline-broken --repo . --output-format yaml

# 4. Compare new plan (from broken code) against enriched plan
specfact --no-banner plan compare \
Expand All @@ -902,7 +902,7 @@ mv src/pipeline_original.py src/pipeline.py

**What We've Accomplished**:

1. ✅ Created plan bundle from code (`import from-code`)
1. ✅ Created plan bundle from code (`code import from-code`)
2. ✅ Enriched plan with semantic understanding (added FEATURE-DATAPROCESSOR and 4 stories)
3. ✅ Reviewed plan and improved quality (added target users, value hypothesis, feature acceptance criteria, enhanced story acceptance criteria with Given/When/Then format)
4. ✅ Configured enforcement (balanced preset with HIGH → BLOCK, MEDIUM → WARN, LOW → LOG)
Expand Down Expand Up @@ -973,7 +973,7 @@ def get_user_stats(user_id: str) -> dict:
**Alternative**: CLI-only mode:

```bash
specfact --no-banner import from-code --repo . --output-format yaml
specfact --no-banner code import from-code --repo . --output-format yaml
```
Comment thread
djm81 marked this conversation as resolved.

**Note**: Interactive mode creates valid plan bundles with features. CLI-only may show 0 features for minimal test cases. Use `--no-banner` before the command to suppress banner output: `specfact --no-banner <command>`.
Expand Down Expand Up @@ -1064,7 +1064,7 @@ This automatically generates `[tool.crosshair]` configuration in `pyproject.toml

**What We've Accomplished**:

1. ✅ Created plan bundle from code (`import from-code`)
1. ✅ Created plan bundle from code (`code import from-code`)
2. ✅ Enriched plan with semantic understanding (if using interactive mode)
3. ✅ Configured enforcement (balanced preset)
4. ✅ Ran validation suite (`specfact code repro`)
Expand Down Expand Up @@ -1143,7 +1143,7 @@ result = process_order(order_id="123")
**Alternative**: CLI-only mode:

```bash
specfact --no-banner import from-code --repo . --output-format yaml
specfact --no-banner code import from-code --repo . --output-format yaml
```

**Important**: After creating the initial plan, we need to make it the default plan so `plan compare --code-vs-plan` can find it. Use `plan select` to set it as the active plan:
Expand Down Expand Up @@ -1225,7 +1225,7 @@ Create `.git/hooks/pre-commit`:
#!/bin/sh
# First, import current code to create a new plan for comparison
# Use default name "auto-derived" so plan compare --code-vs-plan can find it
specfact --no-banner import from-code --repo . --output-format yaml > /dev/null 2>&1
specfact --no-banner code import from-code --repo . --output-format yaml > /dev/null 2>&1

# Then compare: uses active plan (set via plan select) as manual, latest code-derived plan as auto
specfact --no-banner plan compare --code-vs-plan
Expand All @@ -1243,7 +1243,7 @@ specfact --no-banner plan compare --code-vs-plan
**Note**: The `--code-vs-plan` flag automatically uses:

- **Manual plan**: The active plan (set via `plan select`) or `main.bundle.yaml` as fallback
- **Auto plan**: The latest `auto-derived` project bundle (from `import from-code auto-derived` or default bundle name)
- **Auto plan**: The latest `auto-derived` project bundle (from `code import from-code auto-derived` or default bundle name)

Make it executable:

Expand Down Expand Up @@ -1320,7 +1320,7 @@ Fix the blocking deviations or adjust enforcement config

**What We've Accomplished**:

1. ✅ Created initial plan bundle from original code (`import from-code`)
1. ✅ Created initial plan bundle from original code (`code import from-code`)
2. ✅ Committed the original plan (baseline)
3. ✅ Modified code to introduce breaking change (added required `user_id` parameter)
4. ✅ Configured enforcement (balanced preset with HIGH → BLOCK)
Expand Down Expand Up @@ -1578,7 +1578,7 @@ rm -rf specfact-integration-tests

**What's Validated**:

- ✅ Plan bundle creation (`import from-code`)
- ✅ Plan bundle creation (`code import from-code`)
- ✅ Plan enrichment (LLM adds features and stories)
- ✅ Plan review (identifies missing items)
- ✅ Story addition via CLI (`plan add-story`)
Expand All @@ -1605,7 +1605,7 @@ rm -rf specfact-integration-tests

**What's Validated**:

- ✅ Plan bundle creation (`import from-code`)
- ✅ Plan bundle creation (`code import from-code`)
- ✅ Plan enrichment (LLM adds FEATURE-DATAPROCESSOR and 4 stories)
- ✅ Plan review (auto-enrichment adds target users, value hypothesis, feature acceptance criteria, enhanced story acceptance criteria)
- ✅ Enforcement configuration (`enforce stage` with BALANCED preset)
Expand All @@ -1627,7 +1627,7 @@ rm -rf specfact-integration-tests

**What's Validated**:

- ✅ Plan bundle creation (`import from-code`)
- ✅ Plan bundle creation (`code import from-code`)
- ✅ Plan selection (`plan select` sets active plan)
- ✅ Enforcement configuration (`enforce stage` with BALANCED preset)
- ✅ Pre-commit hook setup (imports code, then compares)
Expand All @@ -1636,7 +1636,7 @@ rm -rf specfact-integration-tests

**Test Results**:

- Plan creation: ✅ `import from-code <bundle-name>` creates project bundle at `.specfact/projects/<bundle-name>/` (modular structure)
- Plan creation: ✅ `code import from-code <bundle-name>` creates project bundle at `.specfact/projects/<bundle-name>/` (modular structure)
- Plan selection: ✅ `plan select` sets active plan correctly
- Plan comparison: ✅ `plan compare --code-vs-plan` finds:
- Manual plan: Active plan (set via `plan select`)
Expand All @@ -1647,9 +1647,9 @@ rm -rf specfact-integration-tests

**Key Findings**:

- ✅ `import from-code` should use bundle name "auto-derived" so `plan compare --code-vs-plan` can find it
- ✅ `code import from-code` should use bundle name "auto-derived" so `plan compare --code-vs-plan` can find it
- ✅ `plan select` is the recommended way to set the baseline plan (cleaner than copying to `main.bundle.yaml`)
- ✅ Pre-commit hook workflow: `import from-code` → `plan compare --code-vs-plan` works correctly
- ✅ Pre-commit hook workflow: `code import from-code` → `plan compare --code-vs-plan` works correctly
- ✅ Enforcement configuration is respected (HIGH → BLOCK based on preset)

**Conclusion**: Example 4 is **fully validated**. The pre-commit hook integration works end-to-end. The hook successfully imports current code, compares it against the active plan, and blocks commits when HIGH severity deviations are detected. The workflow demonstrates how SpecFact prevents breaking changes from being committed locally, before they reach CI/CD.
Expand Down Expand Up @@ -1687,7 +1687,7 @@ rm -rf specfact-integration-tests
Example 5 follows a similar workflow and should be validated using the same approach:

1. Create test files
2. Create plan bundle (`import from-code`)
2. Create plan bundle (`code import from-code`)
3. Enrich plan (if needed)
4. Review plan and add missing items
5. Configure enforcement
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -338,7 +338,7 @@ result = process_order(order_id="123") # ⚠️ Missing user_id
#!/bin/sh
# Import current code to create a new plan for comparison
# Use bundle name "auto-derived" so plan compare --code-vs-plan can find it
specfact --no-banner import from-code auto-derived --repo . --output-format yaml > /dev/null 2>&1
specfact --no-banner code import from-code auto-derived --repo . --output-format yaml > /dev/null 2>&1

# Compare: uses active plan (set via plan select) as manual, latest auto-derived plan as auto
specfact --no-banner plan compare --code-vs-plan
Expand Down
6 changes: 3 additions & 3 deletions docs/examples/quick-examples.md
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ specfact code import my-project --repo . --confidence 0.7
specfact code import my-project --repo . --shadow-only

# CoPilot mode (enhanced prompts)
specfact --mode copilot import from-code my-project --repo . --confidence 0.7
specfact --mode copilot code import from-code my-project --repo . --confidence 0.7

# Re-validate existing features (force re-analysis)
specfact code import my-project --repo . --revalidate-features
Expand Down Expand Up @@ -200,10 +200,10 @@ specfact init ide --ide cursor --force
specfact code import my-project --repo .

# Force CI/CD mode
specfact --mode cicd import from-code my-project --repo .
specfact --mode cicd code import from-code my-project --repo .

# Force CoPilot mode
specfact --mode copilot import from-code my-project --repo .
specfact --mode copilot code import from-code my-project --repo .

# Set via environment variable
export SPECFACT_MODE=copilot
Expand Down
2 changes: 1 addition & 1 deletion docs/getting-started/installation.md
Original file line number Diff line number Diff line change
Expand Up @@ -353,7 +353,7 @@ specfact code import my-project \
--report analysis.md

# Analyze with CoPilot mode (enhanced prompts - CLI only, not for IDE)
specfact --mode copilot import from-code my-project \
specfact --mode copilot code import from-code my-project \
--repo ./my-project \
--confidence 0.7 \
--report analysis.md
Expand Down
6 changes: 3 additions & 3 deletions docs/guides/copilot-mode.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ Mode is auto-detected based on environment, or you can explicitly set it with `-

```bash
# Explicitly enable CoPilot mode
specfact --mode copilot import from-code legacy-api --repo . --confidence 0.7
specfact --mode copilot code import from-code legacy-api --repo . --confidence 0.7

# Mode is auto-detected based on environment (IDE integration, CoPilot API availability)
specfact code import legacy-api --repo . --confidence 0.7 # Auto-detects CoPilot if available
Expand Down Expand Up @@ -98,10 +98,10 @@ This context is used to generate enhanced prompts that instruct the AI IDE to:

```bash
# CI/CD mode (fast, deterministic, Python-only)
specfact --mode cicd import from-code --repo . --confidence 0.7
specfact --mode cicd code import from-code --repo . --confidence 0.7

# CoPilot mode (AI-first, semantic understanding, multi-language)
specfact --mode copilot import from-code --repo . --confidence 0.7
specfact --mode copilot code import from-code --repo . --confidence 0.7

# Output (CoPilot mode):
# Mode: CoPilot (AI-first analysis)
Expand Down
6 changes: 3 additions & 3 deletions docs/guides/troubleshooting.md
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,7 @@ specfact project health-check
4. **Use CoPilot mode** (recommended for brownfield - better semantic understanding):

```bash
specfact --mode copilot import from-code legacy-api --repo . --confidence 0.7
specfact --mode copilot code import from-code legacy-api --repo . --confidence 0.7
```

5. **For legacy codebases**, start with minimal confidence and review extracted features:
Expand Down Expand Up @@ -445,7 +445,7 @@ specfact project health-check
1. **Use explicit mode**:

```bash
specfact --mode copilot import from-code my-project --repo .
specfact --mode copilot code import from-code my-project --repo .
```

2. **Check environment variables**:
Expand Down Expand Up @@ -477,7 +477,7 @@ specfact project health-check
1. **Use CI/CD mode** (faster):

```bash
specfact --mode cicd import from-code my-project --repo .
specfact --mode cicd code import from-code my-project --repo .
```

2. **Increase confidence threshold** (fewer features):
Expand Down
2 changes: 1 addition & 1 deletion docs/guides/use-cases.md
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ specfact code import \
--report analysis-core.md

# CoPilot mode (enhanced prompts, interactive)
specfact --mode copilot import from-code \
specfact --mode copilot code import from-code \
--repo . \
--confidence 0.7 \
--report analysis.md
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,25 @@ The upgrade output SHALL distinguish between modules that were actually upgraded
and modules that were already at the latest version. Showing `0.41.16 -> 0.41.16` when no version
change occurred is incorrect and SHALL NOT happen.

While the registry index is being fetched or a module is being installed, the CLI SHALL show visible
progress (for example a Rich status spinner) so the user knows work is ongoing. Rich progress MAY
be suppressed in automated test environments.

Before upgrading any module where the latest registry version has a higher major version than the
installed version, the CLI SHALL warn the user and require confirmation, because major version
bumps may contain breaking changes.

#### Scenario: Upgrade shows progress during registry fetch and install

- **WHEN** user runs `specfact module upgrade` and the registry fetch or an install takes noticeable time
- **THEN** the CLI SHALL show visible progress during fetch and during each module install

#### Scenario: Upgrade warns when registry index is unavailable

- **WHEN** the registry index cannot be fetched (offline or network error)
- **THEN** the CLI SHALL print a clear warning that the registry is unavailable
- **AND** SHALL continue using installed metadata where possible for the upgrade decision

#### Scenario: Upgrade a single named module to a newer minor/patch version

- **WHEN** user runs `specfact module upgrade backlog` and `0.42.0` is available (current `0.41.16`)
Expand Down
Loading
Loading