---

# Stage identity per spec Section 6.1
stage: 2
stage_id: "02"
title: "Documentation Update"
workflow: sync-docs
estimated_tokens: 4000

# Context specification
context:
  static:
    persona: "technical writer updating documentation to match current implementation"
    purpose: "Update outdated .md documentation to accurately reflect current code"
  dynamic:
    - key: exclude_patterns
      source: cli_arg
      default: "specs/**,**/node_modules/**,**/.git/**"
    - key: iterations
      source: cli_arg
      default: 1

# Execution flow with step types
# YAML step -> Markdown section mapping:
#   1 load_findings    -> Step 1: Load Sync Findings
#   2 create_todo      -> Step 2: Create TODO from Findings
#   3 recall_cache     -> Step 3: Update Each Document (recall phase)
#   4 update_docs      -> Step 3: Update Each Document (edit phase)
#   5 verify_updates   -> Step 4: Verify Updates
#   6 handle_orphaned  -> Step 4.5: Handle Orphaned Documentation
#   7 create_missing   -> Step 5: Create New Documentation
#   8 commit_updates   -> Step 6: Commit Updates
#   9 generate_summary -> Step 7: Generate Summary
execution_flow:
  - step: 1
    type: action
    name: load_findings
    instruction: "Load sync findings from Stage 1 cache"
    output_variable: sync_findings
  - step: 2
    type: action
    name: create_todo
    instruction: "Create TODO list from findings organized by priority"
    output_variable: todo_list
  - step: 3
    type: action
    name: recall_cache
    instruction: "Recall cached understanding for each file being updated"
  - step: 4
    type: input_loop
    id: update_docs
    instruction: "Update each outdated document using civyk-repoix for accurate code info"
    prompt: "Updating documentation from findings"
    blocking: true
  - step: 5
    type: action
    name: verify_updates
    instruction: "Verify updates match current implementation using civyk-repoix"
    output_variable: verification_passed
  - step: 6
    type: action
    name: handle_orphaned
    instruction: "Handle orphaned documentation - delete or update docs referencing deleted code"
  - step: 7
    type: action
    name: create_missing_docs
    instruction: "Create new documentation for undocumented code identified in Stage 1"
  - step: 8
    type: action
    name: commit_updates
    instruction: "Commit updated documentation with appropriate message"
  - step: 9
    type: action
    name: generate_summary
    instruction: "Generate update summary"
    output_variable: summary

# Guardrails
guardrails:
  enforcement: active
  allowed_tools:
    - civyk-repoix
    - Read
    - Edit
    - Write
    - Grep
    - Glob
    - Bash
  forbidden_actions:
    - "Delete production source files"
    - "Modify non-documentation files"
    - "Update files in specs/ folder"
    - "Push to remote without user confirmation"
  file_restrictions:
    allowed_paths:
      - "**/*.md"
    forbidden_paths:
      - "specs/**"
      - ".env"
      - "**/*.key"
      - "**/credentials*"
  read_only: false

# Output specification
output:
  state_update:
    sync-docs.current_stage: "02-update"
  completion_command: "civyk-hatch update-stage sync-docs 02 --status completed"

# Next stage - loops back to 01 until all docs synced
next:
  stage: 1
  stage_id: "01"
  command: "civyk-hatch sync-docs --stage=1 --iterations={next_iteration}"
  auto_continue: true
  is_terminal: false
  condition: "documentation still out of sync"
version: 1.0.0
---

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

{{include:ai-cache-enforcement.md}}

# Stage 2: Documentation Update

Update all outdated documentation identified in Stage 1 to accurately reflect the current implementation.

## Prerequisites

- Stage 01 completed with sync report generated
- Mode: `{REPOIX_MODE}` - re-derived in Step 1 (also stored in `documentation-sync` cache by Stage 1 when repoix available)
- If "cli", convert MCP calls per table below
- Sync findings available in AI cache (or session context when REPOIX_MODE = "none")
- **NOTE: When REPOIX_MODE = "none", ALL repoix tools are unavailable including AI cache tools (`understand(action="recall")`, `understand(action="store")`, `understand(action="invalidate")`, `understand(action="stats")`). Skip these calls and fall through to manual fallbacks (Read, Grep, Glob).**

## Critical Rules

| Rule | Action |
|------|--------|
| Exclude specs/ | **NEVER** update files in specs/ folder |
| Verify before update | **MUST** read actual code before updating docs |
| Commit atomically | **MUST** commit only .md files |
| Real-time status | **MUST** emit status after each document updated |
| **Use branch diff** | **MUST** use branch diff findings to prioritize updates |
| **understand recall first** | **MUST** call `understand(action="recall", target=<code_path>)` before expensive repoix calls. Use cached purpose, key_points, analysis for accurate content |
| **Functionality over counts** | **MUST** update documented functionality, architecture, and behavior descriptions FIRST. Counts are secondary. A doc with correct counts but wrong architecture is worse than the reverse |

---

## Real-Time Status Updates

Emit status updates as each document is processed:

```text
# After EACH document is updated:
OUTPUT: "[{completed}/{total}] [ok] {doc_path} - {action}"

# Example outputs:
"[1/8] [ok] docs/api.md - updated (3 sections)"
"[2/8] [ok] README.md - updated (installation)"
"[3/8] [ok] docs/services.md - created (new)"
"[4/8] ~ docs/legacy.md - skipped (intentional)"

# Update todo for visual progress:
TodoWrite: "Updating docs: {completed}/{total} complete ({pct}%)"
```

---

## Checkpointing & Resume

### Save Checkpoint After Each Document

```text
# [!] PREREQUISITE: Requires repoix (skip when REPOIX_MODE == "none")
IF REPOIX_MODE == "none":
    SKIP checkpoint

# After updating each document (for large doc sets):
IF total_docs > 10:
    understand(action="store",
        scope="project",
        target="sync-docs-checkpoint",  # Unique to sync-docs workflow
        purpose="sync-docs workflow checkpoint for Stage 2",
        importance="high",
        key_points=[
            "stage: 2",
            "iteration: {iterations}",
            "docs_updated: {updated_count}",
            "docs_remaining: {remaining_count}"
        ],
        gotchas=["Resume with: civyk-hatch sync-docs --resume"],
        analysis="Stage 2 in progress. {updated_count}/{total} docs processed."
    )
```

### Clear Checkpoint on Completion

```text
# After Stage 2 completes:
# [!] PREREQUISITE: Requires repoix (skip when REPOIX_MODE == "none")
IF REPOIX_MODE == "none":
    SKIP checkpoint clear

# understand(action="invalidate") is an AI cache operation that marks stale entries
# for re-analysis. This clears the checkpoint so the next run starts fresh.
understand(action="invalidate", target="sync-docs-checkpoint")
```

---

## Understand Workflow Cache Integration

**CRITICAL: Use cached understanding from understand workflow to inform documentation updates. This provides accurate code information without expensive repoix calls.**

**NOTE: This section runs AFTER Step 1 (which loads REPOIX_MODE from Stage 1 cache). If REPOIX_MODE == "none", skip to Step 2.**

### Check Available Understanding

```text
# [!] PREREQUISITE: Requires repoix (REPOIX_MODE set by Step 1)
IF REPOIX_MODE == "none":
    OUTPUT: "=== NO REPOIX - Skipping understand cache check ==="
    SKIP to Step 2

# [!] MANDATORY: Check understand workflow cache status
understand(action="stats", limit=100)

# Determine what understanding is available
understand(action="recall", target="project")
# IF found AND fresh: Use project architecture for context

# For each file to be updated, check related code understanding
FOR each doc_file in sync_findings.outdated:
    FOR each code_ref in doc_file.code_references:
        understand(action="recall", target="<code_file_path>")
        # IF found AND fresh: Use cached understanding instead of repoix calls
```

### Understanding-Informed Updates

When cached understanding is available:

| Update Need | Use From Cache |
|-------------|----------------|
| Function signature | `key_points` from file understanding |
| Class methods | `key_points` from file understanding |
| Module purpose | `purpose` + `analysis` from module understanding |
| Architecture | `key_points` + `analysis` from project understanding |
| Relationships | `gotchas` + `analysis` from module understanding |

---

## MCP/CLI Conversion Table

| MCP Call | CLI Equivalent |
|----------|----------------|
| `symbol(action="detail", fqn="...")` | `civyk-repoix query symbol --action detail --fqn "..."` |
| `search(action="symbols", query="...", kind="...")` | `civyk-repoix query search --action symbols --query "..." --kind "..."` |
| `file(action="symbols", path="...", kinds=["..."])` | `civyk-repoix query file --action symbols --path "..." --kinds "..."` |
| `file(action="imports", path="...")` | `civyk-repoix query file --action imports --path "..."` |
| `symbol(action="hierarchy", fqn="...", direction="both")` | `civyk-repoix query symbol --action hierarchy --fqn "..." --direction both` |
| `symbol(action="references", fqn="...")` | `civyk-repoix query symbol --action references --fqn "..."` |
| `symbol(action="callers", fqn="...", depth=N)` | `civyk-repoix query symbol --action callers --fqn "..." --depth N` |
| `architecture(action="endpoints", limit=N)` | `civyk-repoix query architecture --action endpoints --limit N` |
| `context(action="task", task="...", token_budget=N)` | `civyk-repoix query context --action task --task "..." --token-budget N` |
| `file(action="related", path="...")` | `civyk-repoix query file --action related --path "..."` |
| `tests(action="for_file", path="...")` | `civyk-repoix query tests --action for_file --path "..."` |
| `git(action="diff", base_branch="...", include_symbols=true)` | `civyk-repoix query git --action diff --base-branch "..." --include-symbols true` |

---

## Step 1: Load Sync Findings

```text
# Load findings from Stage 1
# [!] NOTE: understand(action="recall") requires repoix. When REPOIX_MODE was "none" in Stage 1,
# findings were OUTPUT to session context instead of stored. Use session context as fallback.

# Step 1a: Re-derive REPOIX_MODE (don't rely solely on cache)
TRY: status(action="check")
    REPOIX_MODE = "mcp"
EXCEPT:
    TRY: Bash: civyk-repoix query status --action check
        REPOIX_MODE = "cli"
    EXCEPT:
        REPOIX_MODE = "none"

IF REPOIX_MODE != "none":
    understand(action="recall", target="documentation-sync")
    # Extract:
    # - repoix_mode: Discovery mode from Stage 1 (mcp|cli|none)
    # - outdated_architecture: files with stale architecture/functionality descriptions (PRIORITY)
    # - outdated_counts: files with stale counts/references only
    # - orphaned: files referencing deleted code
    # - missing: new code needing documentation
ELSE:
    # No repoix - use Stage 1 findings from session context (auto_continue preserves context)
    OUTPUT: "=== NO REPOIX - Using Stage 1 findings from session context ==="

OUTPUT: "Using discovery mode: {REPOIX_MODE}"

# [!] CRITICAL: Also load branch diff findings for targeted updates
IF REPOIX_MODE != "none":
    understand(action="recall", target="sync-docs-branch-diff")
    # Extract:
    # - new_modules: New code modules that need documentation
    # - new_classes: New classes that need documentation
    # - new_functions: New public functions that need documentation
    # - outdated_refs_found: Docs with outdated counts/references (e.g., "36 tools" -> "42 tools")
    # - files_changed: All files changed in branch (for cross-referencing)

# Merge branch diff findings with scan findings
IF branch_diff findings exist:
    # Add outdated refs to update list (deduplicate against scan findings)
    FOR each outdated_ref in branch_diff.outdated_refs_found:
        IF outdated_ref.path NOT already in sync_findings.outdated:
            add to HIGH PRIORITY updates

    # Add missing docs for new features
    FOR each new_module in branch_diff.new_modules:
        IF not documented:
            add to MISSING documentation list

ELSE:  # No branch diff available
    # Running on main branch or Stage 1 Step 2 was skipped
    # Continue with standard scan findings only
    OUTPUT: "[INFO] No branch diff findings - using scan findings only"
```

---

## Step 2: Create TODO from Findings

```text
TODO (Iteration {iterations})
=============================

HIGH PRIORITY - Architecture/Functionality (fix FIRST per "Functionality over counts" rule):
[ ] README.md:20-45 - Architecture describes REST but code uses gRPC [ARCH]
[ ] docs/architecture.md:10-30 - Data flow missing EventPipe component [ARCH]
[ ] docs/services.md - Add NewService documentation [MISSING]

HIGH PRIORITY - Counts/References:
[ ] docs/api.md:45-52 - Function name auth() -> authenticate() [COUNT]
[ ] README.md:12-15 - Installation command update [COUNT]

MEDIUM PRIORITY:
[ ] docs/config.md:30-40 - Add new configuration options
[ ] CONTRIBUTING.md:20 - Update test command

LOW PRIORITY:
[ ] docs/faq.md:15 - Minor wording update
```

---

## Step 3: Update Each Document

For each TODO item:

### 3.1 Get Accurate Code Information

**[!] MANDATORY: ALWAYS try `understand(action="recall")` first before calling expensive repoix tools. The cached understanding contains purpose, functionality, architecture insights, and gotchas that are essential for accurate documentation updates.**

```text
# Collect all code paths referenced by this doc's TODO item
referenced_paths = extract code file/module paths from TODO item and doc content

FOR each code_path in referenced_paths[:10]:  # Cap at 10 paths per TODO item
    # STEP A: understand(action="recall") FIRST
    result = understand(action="recall", target=code_path)
    # Returns: purpose, key_points, gotchas, analysis, dependencies
    # This tells you WHAT the code actually does, WHY it exists, and HOW it works

    # Use cached understanding to:
    # - Write accurate descriptions of functionality and architecture
    # - List actual features and capabilities (from key_points)
    # - Note important behaviors and edge cases (from gotchas)
    # - Describe component relationships (from analysis)

    # STEP B: Only call repoix tools for details NOT in cache
    IF NOT result.found OR NOT result.fresh:
        IF REPOIX_MODE != "none":
            # For specific signatures not in cache:
            symbol(action="detail", fqn="<symbol_in_code_path>")

            # For class details not in cache:
            file(action="symbols", path=code_path, kinds=["method"], include_private=false)

            # For understanding code context when no cache:
            context(action="task", task="document <symbol_name>", token_budget=2000)
        ELSE:
            # Manual fallback: read source file directly
            Read(file_path=code_path)
    ELSE:
        # Cache hit - only fetch specifics not covered by understand(action="recall")
        # (e.g., exact parameter types, return types for signature docs)

# For API endpoint specifics (call ONCE, not per path):
IF doc references API endpoints AND REPOIX_MODE != "none":
    architecture(action="endpoints", limit=200)
```

### 3.2 Understand the Change

**[!] CRITICAL: Don't just check signatures and counts. Verify WHAT the code does, its architecture, and its behavior.**

| Question | Tool to Use |
|----------|-------------|
| **What does this code actually do?** | `understand(action="recall", target=...)` - check purpose + key_points |
| **How does the architecture work?** | `understand(action="recall", target=...)` - check analysis field |
| **What are the gotchas/edge cases?** | `understand(action="recall", target=...)` - check gotchas field |
| What's the new function signature? | `symbol(action="detail", fqn=...)` (only if not in cache) |
| What parameters changed? | `file(action="symbols", path=..., kinds=["function"])` |
| What classes inherit from this? | `symbol(action="hierarchy", fqn=..., direction="down")` |
| Who uses this API? | `symbol(action="callers", fqn=..., depth=3)` |
| What tests exist? | `tests(action="for_file", path=...)` |
| What files are related? | `file(action="related", path=...)` |

### 3.3 Update Documentation

**[!] PRIORITY ORDER: Update functionality and architecture FIRST, then counts/references.**

**Good updates (based on understand(action="recall") + repoix data):**
- **Accurate descriptions of what the code does** (from understand(action="recall") purpose + key_points)
- **Correct architecture and component interactions** (from understand(action="recall") analysis)
- **Complete feature/capability lists** (from understand(action="recall") key_points)
- **Important gotchas and edge cases** (from understand(action="recall") gotchas)
- Accurate function signatures from `symbol(action="detail")`
- Correct parameter names and types
- Valid class hierarchies from `symbol(action="hierarchy")`
- Accurate counts derived from actual code (not hardcoded)

**Bad updates:**
- Generic placeholder text
- Speculation about code behavior
- Updating only counts while leaving stale architecture descriptions
- Listing features without verifying they still exist
- Describing workflows that were refactored

### 3.3.1 Update Functionality and Architecture (PRIORITY)

```text
# [!] CRITICAL: This is the MOST IMPORTANT part of doc updates.
# Counts going stale is minor. Architecture/functionality going stale is major.

# This runs inside the per-TODO-item loop for the current doc being updated.

# 1. Identify all prose claims about architecture/functionality/behavior
arch_claims = extract architecture, workflow, and functionality descriptions from doc

# 2. understand(action="recall") for all referenced code files/modules
referenced_paths = extract code paths from doc
# Prioritize: branch-diff changed files first, then rest
IF branch_diff available:
    changed_set = set(branch_diff.files_changed)
    referenced_paths = sorted(referenced_paths,
        key=lambda p: (p not in changed_set, p))  # changed files first
FOR each path in referenced_paths[:15]:
    result = understand(action="recall", target=path)
    IF result.found AND result.fresh:
        # 3. Compare doc's prose against cached understanding
        IF doc.purpose_description != result.purpose:
            Edit: update purpose description to match result.purpose
        IF doc.feature_list is SUBSET of result.key_points:
            Edit: add missing features from result.key_points
        IF doc.architecture_description CONTRADICTS result.analysis:
            Edit: rewrite architecture section using result.analysis
        IF doc misses important result.gotchas:
            Edit: add gotchas/caveats section
    ELSE:
        # No cache - read the actual source file
        Read(file_path=path)
        # Compare doc prose against actual code, update accordingly

# Common stale patterns to fix:
# - "This module handles X" -> actually handles X, Y, and Z now
# - "Architecture: A connects to B" -> C was added in between
# - "Supports features: [list]" -> list is incomplete or has removed items
# - "Uses technology X" -> migrated to Y
# - "Workflow: step1 -> step2" -> step1a was added
```

### 3.3.2 Update Counts and References

```text
# [!] When updating counts, feature lists, API references, etc.
# ALWAYS derive from actual code, not from previous docs

# Get actual counts (only if counts appear in the doc)
IF REPOIX_MODE != "none":
    api_results = architecture(action="endpoints", limit=1)  # Only need total_count
    api_count = api_results.total_count

    class_results = search(action="symbols", query="%", kind="class", limit=1)  # Only need total_count
    class_count = class_results.total_count
ELSE:
    # Manual fallback: skip count verification when repoix unavailable
    OUTPUT: "[INFO] Count verification skipped - no repoix available"

# Use branch diff findings (already loaded in Step 1, don't re-recall)
FOR each outdated_ref in branch_diff.outdated_refs_found:
    # Replace old count/reference with actual from code

FOR each new_module in branch_diff.new_modules:
    # Add documentation section for new feature
    # Derive content from understand(action="recall"), not speculation
```

### 3.4 Mark Complete

```text
[X] Updated: docs/api.md:45-52 - auth() -> authenticate()
    Verified: symbol(action="detail", fqn="module.authenticate") returns correct signature
```

Skip with evidence:
```text
[SKIP] docs/legacy.md - File intentionally documents legacy behavior
       Verified: No current code references this pattern
```

---

## Step 4: Verify Updates

For each updated document, verify accuracy:

### 4.0 Verify Architecture and Functionality (PRIORITY)

```text
# [!] CRITICAL: Verify updated prose descriptions match reality, not just symbols.
FOR each updated_doc in updated_docs:
    # understand(action="recall") for key referenced modules
    FOR each code_path in updated_doc.referenced_paths[:10]:
        result = understand(action="recall", target=code_path)
        IF result.found AND result.fresh:
            # Verify updated doc descriptions match cached understanding
            # - Does updated purpose description match result.purpose?
            # - Does updated feature list cover result.key_points?
            # - Does updated architecture match result.analysis?
            IF any mismatch found:
                OUTPUT: "[WARN] {updated_doc.path}: updated content still doesn't match {code_path}"
                flag for re-update
        ELSE:
            # No cache or stale - read source to verify
            Read(file_path=code_path)
            IF REPOIX_MODE != "none":
                file(action="symbols", path=code_path, kinds=["class", "function", "method"])
            # Compare updated doc against actual source code
            IF doc descriptions don't match source:
                OUTPUT: "[WARN] {updated_doc.path}: uncached path {code_path} needs manual check"
                flag for re-update
```

### 4.1 Verify Code References

```text
IF REPOIX_MODE != "none":
    # For each documented symbol:
    symbol(action="detail", fqn="documented.function")
    # Confirm: symbol exists, signature matches doc

    # For each documented class:
    file(action="symbols", path="<class_file>", kinds=["class", "method"])
    # Confirm: all methods documented correctly

    # For each documented API:
    architecture(action="endpoints", limit=200)
    # Confirm: endpoint exists with documented parameters
ELSE:
    # Manual fallback: read source files to verify references
    FOR each code_ref in updated_doc.code_references[:15]:
        Read(file_path=code_ref.source_file)
        # Manually verify symbol exists and signature matches doc
```

### 4.2 Verify Examples Work

```text
IF REPOIX_MODE != "none":
    # Check if documented examples are valid:
    tests(action="for_file", path="<documented_module>", include_indirect=true)
    # Compare test patterns with documented examples
ELSE:
    # Manual fallback: search for test files
    Glob(pattern="**/test*<module_name>*")
    # Read test files to verify examples match
```

### 4.3 Verify CLI Commands

```bash
# Test documented CLI commands (dry-run if destructive)
command --help
# Verify flags and options match documentation
```

---

## Step 4.5: Handle Orphaned Documentation

For each ORPHANED doc identified in Stage 1:

```text
FOR each orphaned_doc in sync_findings.orphaned:
    Read(file_path=orphaned_doc.path)

    # Safety check: never auto-delete docs with historical value
    IF orphaned_doc.path matches "CHANGELOG|HISTORY|ARCHIVE|MIGRATION":
        OUTPUT: "[SKIP] {orphaned_doc.path} - historical doc, flagging for manual review"
        CONTINUE  # Skip to next orphaned doc

    # Determine action based on content
    IF entire doc references only deleted code:
        # Delete if no historical value
        OUTPUT: "[ORPHAN] {orphaned_doc.path} - all references deleted, removing"
        Bash: git rm {orphaned_doc.path}

    ELSE IF doc has some valid content mixed with orphaned refs:
        # Update to remove orphaned references, check for renames
        FOR each orphaned_ref in orphaned_doc.deleted_refs[:10]:
            IF REPOIX_MODE != "none":
                symbol(action="similar", fqn=orphaned_ref, similarity_threshold=0.6, limit=5)
            ELSE:
                # Fallback: search for similar names in codebase
                Grep(pattern=orphaned_ref, glob="*.py,*.ts,*.js")
            IF similar found:
                # Code was renamed/moved - update reference
                Edit: replace orphaned_ref with similar match
            ELSE:
                # Code was truly deleted - remove the section
                Edit: remove section referencing orphaned_ref

    OUTPUT: "[{completed}/{total}] [ok] {orphaned_doc.path} - {action}"
```

---

## Step 5: Create New Documentation (MISSING)

For undocumented code identified in Stage 1:

### 5.1 Gather Code Information

```text
# [!] MANDATORY: understand(action="recall") FIRST
result = understand(action="recall", target="src/services/new.py")
# IF found AND fresh: Use purpose, key_points, gotchas, analysis
# to write accurate documentation without additional repoix calls

# Only call repoix tools for details NOT available in cache:
IF NOT result.found OR NOT result.fresh:
    IF REPOIX_MODE != "none":
        symbol(action="detail", fqn="module.NewService")
        file(action="symbols", path="src/services/new.py", include_private=false)
        symbol(action="hierarchy", fqn="module.NewService", direction="both", depth=3)
        file(action="imports", path="src/services/new.py")
        tests(action="for_file", path="src/services/new.py")
        context(action="task", task="create documentation for NewService", token_budget=3000)
    ELSE:
        # Manual fallback: read source file directly
        Read(file_path="src/services/new.py")
        Glob(pattern="**/test*new*")  # Find related tests
ELSE:
    # Cache hit - only fetch specific details not in cache
    IF REPOIX_MODE != "none":
        tests(action="for_file", path="src/services/new.py")  # Always useful for Usage section
    ELSE:
        Glob(pattern="**/test*new*")  # Find related tests manually
```

### 5.2 Create Documentation File

Write new documentation based on civyk-repoix analysis:

```markdown
# NewService

## Overview
[Purpose and summary from understand(action="recall") - use purpose + key_points]

## Architecture
[Component relationships and design from understand(action="recall") - use analysis]

## API

### Methods
[From understand(action="recall") key_points, supplemented by file(action="symbols") if needed]

### Parameters
[From symbol(action="detail") signatures for specific details not in cache]

## Important Notes
[From understand(action="recall") gotchas - edge cases, caveats, known limitations]

## Usage
[Examples from tests(action="for_file")]

## Related
[From file(action="related")]
```

### 5.3 Verify New Documentation

```text
# Verify newly created docs - deep check, not just symbol-exists
FOR each new_doc in created_docs:
    # Step A: Verify architecture/functionality descriptions
    FOR each code_path in new_doc.referenced_paths[:10]:
        result = understand(action="recall", target=code_path)
        IF result.found AND result.fresh:
            # Compare doc descriptions against cached understanding
            IF new_doc.purpose_description != result.purpose:
                flag: "Purpose mismatch in {new_doc.path}"
            IF new_doc.feature_list misses result.key_points:
                flag: "Missing features in {new_doc.path}"
        ELSE:
            # No cache - read source to verify
            Read(file_path=code_path)

    # Step B: Verify specific symbols and signatures
    FOR each code_ref in new_doc.symbol_references[:15]:
        IF REPOIX_MODE != "none":
            symbol(action="detail", fqn="<referenced_symbol>")
            # Confirm: symbol exists, signature matches doc
        ELSE:
            Read(file_path="<code_file>")

OUTPUT: "[ok] Verified {created_count} new documentation files"
```

---

## Step 6: Commit Updates

```bash
# Stage only .md files (never stage specs/)
# Using git pathspec negation - simpler and more reliable than piped grep
git add '*.md' ':!specs/**'

# Verify only intended files are staged
git diff --cached --name-only | grep -v '\.md$' && echo "[ERROR] Non-.md files staged!" && exit 1

git commit -m "$(cat <<'EOF'
docs: sync documentation with implementation (iteration {iterations})

Updated:
{FOR each updated_doc: "- {path} - {change_summary}"}

Created:
{FOR each created_doc: "- {path} - {description}"}

Removed:
{FOR each orphaned_doc removed: "- {path} - orphaned"}

Verified against codebase using civyk-repoix.
EOF
)"
```

**Avoid** `git add -A` (may include sensitive files).

---

## Step 7: Generate Summary

```text
Documentation Update Complete (Iteration {iterations})
=====================================================

Discovery Mode: {REPOIX_MODE}

Updated: {updated_count} files
{FOR each updated_doc: "- {path} - {change_summary} (verified with {verification_method})"}

Created: {created_count} files
{FOR each created_doc: "- {path} - {description}"}

Removed: {removed_count} files
{FOR each removed_doc: "- {path} - orphaned"}

Skipped: {skipped_count} files (intentional legacy docs)
Remaining: {remaining_count} files (need further review)

Verification:
- Architecture/functionality descriptions verified with understand(action="recall")
- All symbols verified with symbol(action="detail")
- All signatures verified with file(action="symbols")
- Examples verified against tests(action="for_file")

Commit: {short_hash}
```

---

## Exit Condition

If all documentation now matches implementation:

```text
=== ALL DOCUMENTATION SYNCED ===

All documentation files verified against current implementation.
No remaining outdated, orphaned, or missing documentation.

[ok] DOCUMENTATION SYNC COMPLETE
```

**-> STOP (workflow complete)**

---

## [AUTO-CONTINUE]

After updating documentation, automatically return to Stage 1 to verify all docs are now synced (loop until complete).

```text
# Compute next iteration for Stage 1 loop-back
next_iteration = iterations + 1
```

## NEXT

```bash
civyk-hatch sync-docs --stage=1 --iterations={next_iteration}
```
