---
# Stage identity per spec Section 6.1
stage: 1
stage_id: "01"
title: "Setup & Discovery"
workflow: understand
estimated_tokens: 2000

# Context specification
context:
  static:
    persona: "codebase analyst building hierarchical understanding for AI cache"
    purpose: "Discover files, check staleness, estimate cost, prepare for analysis"
  dynamic:
    - key: user_args
      source: cli_arg
      default: ""
    - key: mode
      source: cli_arg
      default: ""
      allowed: ["quick", "standard", "deep"]
    - key: include
      source: cli_arg
      default: "**/*"
    - key: exclude
      source: cli_arg
      default: "tests/**,vendor/**,node_modules/**,.git/**,dist/**,build/**,.env,*.env,*.key,*.pem,credentials.*,**/secrets/**,**/.secrets/**"
    - key: max_agents
      source: cli_arg
      default: 10
    - key: dry_run
      source: cli_arg
      default: false
    - key: docstrings
      source: cli_arg
      default: false

# Pre-validation checks
pre_validation: []

# Execution flow with step types
execution_flow:
  - step: 1
    type: conditional
    name: check_direct_mode
    instruction: "Check if user_args or mode contains configuration for direct mode"
    condition: "user_args is not empty OR mode is not empty"
  - step: 2
    type: input_required
    id: config_input
    prompt: "Configure: mode (quick/standard/deep), scope (include pattern), exclude pattern"
    blocking: true
    condition: "user_args is empty AND mode is empty"
  - step: 3
    type: action
    name: check_repoix
    instruction: "Check civyk-repoix availability and index status"
    output_variable: repoix_mode
  - step: 4
    type: action
    name: understand_stats
    instruction: "Get current AI cache statistics via understand(action='stats')"
    output_variable: cache_stats
  - step: 5
    type: action
    name: discover_files
    instruction: "Discover all source files using files()"
    output_variable: all_files
  - step: 6
    type: action
    name: check_staleness
    instruction: "Check staleness for each file via understand(action='recall')"
    output_variable: staleness_map
  - step: 7
    type: action
    name: categorize_files
    instruction: "Categorize files as fresh (skip) vs stale (process)"
    output_variable: file_categories
  - step: 8
    type: action
    name: estimate_cost
    instruction: "Estimate token cost based on stale file count"
    output_variable: cost_estimate
  - step: 9
    type: decision
    name: confirm_proceed
    instruction: "Display summary and get user confirmation (unless dry_run)"

# Guardrails
guardrails:
  enforcement: active
  allowed_tools:
    - civyk-repoix
    - Read
    - Grep
    - Glob
    - Bash
  forbidden_actions:
    - "Delete any files"
    - "Modify any source files"
  read_only: true

# Post-validation checks
post_validation:
  - check: repoix_available
    description: "civyk-repoix is available (MCP or CLI)"
    severity: error
  - check: files_discovered
    description: "Source files were discovered"
    severity: error

# Next stage
next:
  stage: 2
  stage_id: "02"
  command: "civyk-hatch understand --stage=2"
  auto_continue: true
  is_terminal: false
version: 1.0.0
---
# Stage 1: Setup & Discovery

Initialize the understand workflow, discover files, check cache staleness, and estimate processing cost.

{{include:strict-execution-mode-lite.md}}

## Prerequisites

- civyk-repoix available (MCP or CLI)
- Source code files to analyze

---

## Direct Mode (Args Provided)

If `{{user_args}}` or `{{mode}}` contains configuration info:

1. Parse mode, include, exclude from args - NO user prompts needed
2. Apply defaults for missing values:
   - `mode` -> "standard" if empty
   - `include` -> "**/*" if empty
   - `exclude` -> "tests/**,vendor/**,node_modules/**,.git/**,dist/**,build/**,.env,*.env,*.key,*.pem,credentials.*,**/secrets/**,**/.secrets/**" if empty
   - `max_agents` -> 10 if empty
   - `dry_run` -> false if empty
   - `docstrings` -> false if empty
3. Jump directly to **Step 3: Check civyk-repoix Mode**

Examples that trigger direct mode:
- `--mode=deep` -> mode=deep, defaults for rest
- `deep src/core/**` -> mode=deep, include=src/core/**
- `quick --exclude=tests/**` -> mode=quick, exclude=tests/**
- `standard --docstrings` -> mode=standard, docstrings=true

---

## Interactive Mode (No Args)

Only if `{{user_args}}` is empty AND `{{mode}}` is empty:

**[STOP: USER_INPUT_REQUIRED]**

Configure understanding analysis:

1. **Mode** - Choose analysis depth:
   - `quick` - File-level only (fastest)
   - `standard` - File + Module synthesis (recommended)
   - `deep` - File + Module + Project synthesis (thorough)

2. **Scope** (optional) - Which files to analyze:
   - Default: All source files (`**/*`)
   - Example: `src/core/**` for specific module

3. **Exclude** (optional) - Patterns to skip:
   - Default: tests, vendor, node_modules, .git, secrets
   - Example: `legacy/**,deprecated/**`

4. **Docstrings** (optional) - Update source code docstrings:
   - Add `--docstrings` to update docstrings during file analysis (Stage 2)
   - Default: disabled (analysis only)

Enter: `<mode> [include_pattern] [--exclude=pattern] [--docstrings]`
Example: `deep src/** --exclude=tests/**` or `standard --docstrings`
Or press Enter for: `standard **/*` (recommended)

---

## Critical Rules

| Rule | Action |
|------|--------|
| Check repoix first | **NEVER** proceed without verified civyk-repoix |
| Pagination | **MUST** fetch all pages when `has_more=true` |
| Respect excludes | **MUST** filter files matching exclude patterns |
| **Security excludes** | **NEVER** process files matching security patterns |
| Dry run exit | **MUST** stop after estimate if `--dry-run` specified |
| Save checkpoint | **MUST** store discovery state for resume capability |

---

## Security Exclusions

**CRITICAL: Never store understanding for sensitive files.**

The following patterns are excluded by default:

| Pattern | Reason |
|---------|--------|
| `.env`, `*.env` | Environment variables with secrets |
| `*.key`, `*.pem` | Private keys and certificates |
| `credentials.*` | Credential files |
| `**/secrets/**` | Secrets directories |
| `**/.secrets/**` | Hidden secrets directories |

**If a file matches these patterns:**
1. Skip the file entirely
2. Do NOT read its contents
3. Do NOT store any understanding
4. Log: `[SECURITY] Skipped: {file_path}`

---

## Checkpointing & Resume

The understand workflow supports checkpointing for graceful interruption handling and resume capability.

### Checkpoint Structure

```text
understand_checkpoint = {
    "stage": 1,
    "status": "in_progress|completed",
    "timestamp": "<ISO timestamp>",
    "discovery": {
        "total_files": <count>,
        "stale_files": [<file_list>],
        "fresh_files": [<file_list>],
        "file_tree": {<tree_structure>}
    },
    "stats": {
        "repoix_mode": "mcp|cli",
        "cache_entries": <count>,
        "estimated_tokens": <count>
    }
}
```

### Save Checkpoint

After completing categorization (Step 7), save checkpoint:

```text
understand(
    action="store",
    scope="project",
    target="understand-checkpoint",
    purpose="Understand workflow checkpoint for Stage 1",
    importance="high",
    key_points=[
        "stage: 1",
        "status: completed",
        "stale_files: {stale_count}",
        "fresh_files: {fresh_count}"
    ],
    gotchas=["Resume with: civyk-hatch understand --resume"],
    analysis="Stage 1 discovery complete. {stale_count} files need processing."
)
```

### Resume from Checkpoint

On workflow start, check for existing checkpoint:

```text
understand(action="recall", target="understand-checkpoint")

IF found AND fresh:
    # Checkpoint exists - offer resume
    OUTPUT: "Found checkpoint from {timestamp}. Stale files: {stale_count}"
    IF user confirms resume:
        # Skip discovery, use cached state
        SKIP to Step 7 (confirmation)
    ELSE:
        # Start fresh
        understand(action="invalidate", target="understand-checkpoint")
```

---

## Step 3: Check civyk-repoix Availability

**Strategy:** Try MCP first, fall back to CLI if MCP fails.

### Step 3a: Try MCP First

```text
status(action="check")
```

**IF MCP succeeds:** Set `REPOIX_MODE = "mcp"` and proceed.

### Step 3b: CLI Fallback (if MCP fails)

```bash
civyk-repoix query status --action check
```

**IF CLI succeeds:** Set `REPOIX_MODE = "cli"` and proceed.

### Step 3c: Neither Available

```text
[x] Cannot connect to civyk-repoix
    - MCP: not available
    - CLI: not available

    To fix:
    1. Install: pip install civyk-repoix
    2. Start daemon: civyk-repoix daemon start
    3. Verify: civyk-repoix query status --action check
```

**STOP** - Cannot proceed without civyk-repoix.

---

## Step 4: Get Current Understanding Stats

```text
understand(action="stats", limit=100)
```

**Record:**
- `total_entries`: Number of cached understandings
- `by_scope`: Breakdown by scope (file, module, project)
- `by_importance`: Breakdown by importance level

---

## Step 5: Discover All Source Files

```text
# Get all source files (with pagination)
files(source_only=true, limit=500, offset=0)

# Continue until has_more=false
WHILE has_more:
    files(source_only=true, limit=500, offset=<next_offset>)
```

**Apply exclude filters:**
- `tests/**` - Test files (default exclude)
- `vendor/**` - Vendored dependencies
- `node_modules/**` - Node dependencies
- `.git/**` - Git internals
- `dist/**`, `build/**` - Build outputs

**Record:**
- `total_files`: Count of discovered files
- `file_tree`: Hierarchical structure by directory

---

## Step 6: Check Staleness for Each File

For each discovered file, check if understanding is cached and fresh:

```text
# Batch check staleness (efficient for large repos)
FOR each file in file_list:
    understand(action="recall", target="<file_path>")

    IF found=true AND fresh=true:
        mark as FRESH (skip in Stage 2)
    ELSE:
        mark as STALE (process in Stage 2)
```

**Optimization:** Group files by directory and check parent understanding first. If module-level understanding is stale, all children are also stale.

---

## Step 7: Categorize Files

| Category | Criteria | Action |
|----------|----------|--------|
| Fresh | `found=true, fresh=true` | Skip in Stage 2 |
| Stale | `found=false` OR `fresh=false` | Process in Stage 2 |

**Build file tree with staleness annotations:**

```text
project/
|-- src/
|   |-- core/
|   |   |-- engine.py      [STALE]
|   |   `-- utils.py       [FRESH]
|   `-- api/
|       |-- routes.py      [STALE]
|       `-- handlers.py    [STALE]
`-- lib/
    `-- helpers.py         [FRESH]
```

---

## Step 8: Estimate Cost

**Token estimates per operation:**

| Operation | Input Tokens | Output Tokens |
|-----------|-------------|---------------|
| File read + analysis | ~2,000 | ~500 |
| understand(action="store") | ~200 | ~50 |
| Module aggregation | ~1,500 | ~400 |
| Project synthesis | ~3,000 | ~800 |

**Calculate based on mode:**

| Mode | Stages | Estimate |
|------|--------|----------|
| `quick` | File-level only | stale_files × 2.5K tokens |
| `standard` | File + Module | + modules × 2K tokens |
| `deep` | File + Module + Project | + 5K tokens |

---

## Step 9: Display Summary

```text
=== UNDERSTAND WORKFLOW - SETUP ===

Repository: <project_name>
Mode: {mode}
Discovery Mode: {REPOIX_MODE}

=== DISCOVERY RESULTS ===
Files discovered: {total_files}
|-- Source files: {source_count}
|-- Config files: {config_count}

Understanding status:
|-- Fresh (skip): {fresh_count} ({fresh_pct}%)
|-- Stale (process): {stale_count} ({stale_pct}%)

Directories to process:
|-- Deepest level: {max_depth}
|-- Total directories: {dir_count}

=== EXISTING CACHE STATUS ===
Cache entries: {cache_entries}
|-- File-level: {file_entries}
|-- Module-level: {module_entries}
|-- Project-level: {project_entries}
Cache age: {oldest_entry_age} - {newest_entry_age}

=== PROCESSING PLAN ===

Stage 2 - File Analysis (tier: fast):
|-- Files to process: {stale_count}
|-- Parallel agents: {max_agents}
|-- Batches: {batch_count}

{IF mode in ["standard", "deep"]:}
Stage 3 - Module Aggregation (tier: balanced):
|-- Modules to aggregate: {module_count}
{END IF}

{IF mode == "deep":}
Stage 4 - Project Synthesis (tier: balanced):
|-- Single synthesis task
{END IF}

=== COST ESTIMATE ===
Estimated tokens:
|-- File-level: {stale_count} files × 2.5K = {file_tokens}K tokens
{IF mode in ["standard", "deep"]:}
|-- Module-level: {module_count} modules × 2K = {module_tokens}K tokens
{END IF}
{IF mode == "deep":}
|-- Project-level: 1 × 5K = 5K tokens
{END IF}
|-- Total: {total_tokens}K tokens

Estimated cost: ~${min_cost} - ${max_cost}

=== CHECKPOINT ===
Checkpoint saved: understand-checkpoint
Resume with: civyk-hatch understand --resume
```

---

## Exit Conditions

### Dry Run Exit

If `--dry-run` flag is set:

```text
=== DRY RUN COMPLETE ===

Use 'civyk-hatch understand' (without --dry-run) to proceed.
```

**STOP** - Do not proceed to Stage 2.

### No Stale Files Exit

If `stale_count == 0`:

```text
=== ALL FILES HAVE FRESH UNDERSTANDING ===

All {total_files} source files have valid cached understanding.
No processing needed.

Cache stats:
|-- File entries: {file_entries}
|-- Module entries: {module_entries}
|-- Project entry: {has_project}

[ok] UNDERSTAND COMPLETE - Cache is current
```

**STOP** - Workflow complete.

### User Cancellation

If user declines to proceed:

```text
=== WORKFLOW CANCELLED ===

Run 'civyk-hatch understand --dry-run' to see estimate without processing.
```

**STOP** - User cancelled.

---

## [AUTO-CONTINUE]

If stale files exist and user confirms (or not dry-run), automatically proceed to Stage 2 for file-level analysis.

## NEXT

```bash
civyk-hatch understand --stage=2 --mode={mode} --max-agents={max_agents} --docstrings={docstrings}
```
