# Change Request: CR-005

> Created: 2026-03-18
> Status: Approved
> Classification: Modification to FEATURE-049-F
> Related Feature: FEATURE-049-F (KB AI Librarian & Intake)

## Request Details

**Requestor:** End User (via UIUX Feedback Feedback-20260318-083710)
**Date Received:** 2026-03-18
**Priority:** Medium

## Description

When a user uploads a folder to `.intake/`, the file count in both the upload view and intake view shows 0. This is because the current `get_intake_files()` backend implementation skips directories entirely (`if not entry.is_file(): continue`), only counting individual top-level files.

The change request has two parts:

1. **Fix file count logic:** The count should reflect top-level items (both folders and files) within the `.intake/` directory. Uploaded folders should appear as first-class items.

2. **Add folder tree display in intake view:** The intake file list (currently a flat table) must support displaying folders alongside files. Folders should be expandable/collapsible to reveal their contents (files and sub-folders). Sub-folders follow the same expand/collapse logic recursively. Since the intake view is a file-list view, the UI needs to adapt to show a tree structure while keeping the list-based layout.

## Business Justification

Users upload folders (e.g., via ZIP extraction which preserves folder structure per AC-049-F-09a). The current implementation silently ignores these folders — the intake view shows 0 items despite content being present. This creates a confusing experience where users believe their upload failed. Supporting folder display also enables better organization visibility before AI Librarian processing.

## Impact Analysis

### Classification

**Type:** Modification to FEATURE-049-F

**Reasoning:**
- Uses existing data model (extends `.intake-status.json` and `GET /api/kb/intake` response)
- Same target users (KB users)
- Extends existing workflow (intake file management)
- Reuses existing UI (extends intake table with tree support)
- No new API endpoints needed (extends existing `GET /api/kb/intake`)
- Scoring: MODIFICATION 7 vs NEW_FEATURE 0

### Comparison Matrix

| Aspect | CR Requirement | Existing Feature(s) |
|--------|---------------|---------------------|
| Users | KB users managing intake files | Same — KB users |
| Workflow | Upload folder → see items → expand to browse → process with AI Librarian | Upload files → see flat list → process |
| Data Model | Add `type` field (file/folder), `item_count` for folders, `children` for tree | Flat file list with `name`, `size_bytes`, `status` |
| UI Elements | Tree-style table rows with expand/collapse toggles, folder icons | Flat table rows with file icons only |
| API Endpoints | Extend `GET /api/kb/intake` response shape | Same endpoint, flat response |

### Conflict Analysis

**Conflicts Found:** Yes

| # | Type | Affected Feature | Severity | Classification | Description |
|---|------|-----------------|----------|----------------|-------------|
| 1 | specification | FEATURE-049-F AC-049-F-02a | Low | expected | Says "all intake files are displayed in a table" — needs to say "all intake items (files and folders)" |
| 2 | specification | FEATURE-049-F AC-049-F-06a | Low | expected | Says "total file count" — needs to say "total item count" (files + folders) |
| 3 | specification | FEATURE-049-F AC-049-F-08a | Medium | expected | Backend merges "file metadata from filesystem + status" — needs to also handle folder metadata |
| 4 | dependency | FEATURE-049-F AC-049-F-09a | High | expected | Spec says ZIP extraction preserves folder structure in `.intake/`, but `get_intake_files()` ignores directories — spec-implementation mismatch that CR fixes |
| 5 | dependency | CR-001 (kb-librarian skill) | Medium | expected | Librarian skill reads `.intake/` — must handle nested files within folders when processing |

**Unexpected Conflict Resolution:** None — all conflicts are expected.

**Mitigation Strategy:**
- Conflicts 1-3: Update specification ACs inline (minor wording changes)
- Conflict 4: This CR directly fixes the spec-implementation mismatch
- Conflict 5: Downstream — librarian skill implementation should account for nested files (not blocking for this CR)

### Affected Components

| Component | Impact Level | Details |
|-----------|--------------|---------|
| `kb_service.py` — `get_intake_files()` | High | Must list top-level dirs alongside files, provide folder metadata |
| `kb_routes.py` — `GET /api/kb/intake` | Medium | Response shape extended with `type` field and optional `children` |
| `kb-browse-modal.js` — `_renderIntakeScene()` | High | Must render tree with expand/collapse, folder icons, item counts |
| `kb-browse-modal.js` — `_loadIntakeFiles()` | Medium | May need lazy-load for folder children |
| `.intake-status.json` schema | Medium | Support folder entries (keys ending with `/`) |
| FEATURE-049-F specification | Low | Update ACs for folder-inclusive language |

### Dependencies

- FEATURE-049-A: KB Backend provides `.intake/` constant and tree exclusion — no change needed
- FEATURE-049-E: Upload infrastructure — no change needed (uploads already preserve folder structure for archives)
- CR-001 (kb-librarian skill): Downstream impact — skill should process files inside folders

## Proposed Approach

### Backend Changes
1. Update `get_intake_files()` to iterate `.intake/` and include both files and directories as top-level items
2. For each directory entry: count immediate children, provide `type: "folder"` and `item_count`
3. Add an optional query parameter `?children_of=<path>` to `GET /api/kb/intake` to support lazy-loading folder contents
4. Extend `.intake-status.json` to support folder entries (key: `"foldername/"`)

### Frontend Changes
1. Intake table renders rows with `type` discriminator — folders get folder icon + expand toggle, files get file icon
2. Folder rows show `item_count` instead of `size_bytes` in the Size column
3. Clicking expand toggle fetches children (lazy) and renders them indented below the folder row
4. Sub-folders follow the same expand/collapse pattern recursively
5. Statistics count top-level items (folders + files)

### Count Logic
- Top-level count: `len([item for item in .intake/.iterdir() if not item.name.startswith('.')])`
- Excludes hidden files (`.intake-status.json`)
- Counts both files and directories

## Mockup Impact

**UI/UX Change:** Yes
**Existing Mockups Referenced:**

| Original Mockup | Path | Status After CR |
|-----------------|------|-----------------|
| KB Interface v1 — Scene 4 | x-ipe-docs/requirements/EPIC-049/FEATURE-049-F/mockups/kb-interface-v1.html | current (intake table layout still applies, extended with tree rows) |

**Updated Mockup(s):** A new mockup version should be created during feature refinement to show the folder tree UI in the intake table.

## Approval

- [x] Classification approved by human
- [x] Conflict analysis reviewed by human
- [x] Approach approved by human
- [x] Ready for execution

## Execution

**Classification Result:** modification
**Conflicts Resolution:** all_expected

**Actions Taken:**
- [x] CR document created in feature folder
- [x] Conflict analysis completed and documented
- [x] Specification Version History updated with CR link
- [x] Specification ACs updated for folder-inclusive language
- [ ] [If UI/UX CR] New mockup version created during feature refinement
- [x] Next task type set: x-ipe-task-based-feature-refinement

## Links

- Feature Specification: [specification.md](./specification.md)
- Requirement Details: [requirement-details.md](../../requirement-details.md)
- UIUX Feedback: [Feedback-20260318-083710](../../../uiux-feedback/Feedback-20260318-083710/feedback.md)

---

## Change History

| Date | Change | By |
|------|--------|----|
| 2026-03-18 | CR created from UIUX feedback | Ember 🔥 (AI Agent) |
