# Explorer Directory → Project Minimal Implementation Plan

> Status: design-only cleanup for PR #2709. No Project schema or product behavior is implemented by this revision.

## Goal

Replace the Explorer's saved `Directory` resource with a workspace-scoped `Project` resource. Preserve saved Directory data, add explicit Project access grants, and let Reviews reference their Project.

## Approved data model

The Project migration is limited to two new tables and one Review reference:

1. `projects`
   - Project identity and metadata.
   - Carries forward each saved Directory's workspace, machine, root path, display metadata, creator/updater, and timestamps.
   - Adds only the product fields needed for Project: description, visibility, owner member, and lifecycle status.
   - Machine and root are immutable after creation; selecting another machine/root creates another Project.
2. `project_grants`
   - Explicit active-member grants for one Project.
   - V1 roles are `manage` and `view`.
   - The owner is stored on `projects`, is not represented as a grant, and cannot be revoked.
3. nullable `review_contexts.project_id`
   - Backfilled by the same workspace + machine + root identity used by the migrated Directory row.
   - Becomes the durable Review → Project association after product cutover.

No other permanent table or control-plane subsystem is approved.

## Migration rules

- Migration files in the final PR describe only the final approved schema. They must not create temporary tables and remove them in a later migration in the same PR.
- Existing `directories` rows are copied into `projects`; Directory data is not discarded.
- Backfill is database-only. It does not interpret paths through the server working directory and does not call a daemon from SQL.
- Before implementation, a read-only query must report:
  - Directory row count by workspace;
  - duplicate `(workspace_id, machine_id, root_path)` identities, if any;
  - Directory creators that cannot be resolved to active workspace members;
  - Review rows that cannot be matched to a migrated Project by workspace + machine + root.
- Any non-zero anomaly is reported with counts and representative redacted IDs before a write migration is approved. It does not justify adding permanent control-plane tables.
- The final migration sequence must pass fresh install, upgrade, rollback/retry, and bootstrap-vs-migration schema consistency checks.

## Authorization

| Operation | owner | manage grant | view grant | workspace member without grant |
|---|---:|---:|---:|---:|
| list/get Project metadata | yes | yes | yes | only when visibility is `workspace` |
| browse Project files | yes | yes | yes | only when visibility is `workspace` |
| read Project Reviews | yes | yes | yes | only when visibility is `workspace` |
| edit name/description/visibility | yes | yes | no | no |
| manage grants | yes | yes | no | no |
| delete Project metadata | yes | no | no | no |

Additional rules:

- Grant targets must be active human workspace members.
- Unauthorized Project IDs use the repository's existing non-disclosure behavior.
- Deleting a Project removes Project metadata, grants, and its Review associations/rows as approved by the product flow. It never deletes files from the machine.
- API request bodies cannot override a stored Project's workspace, machine, root, or owner authority.

## Product/API replacement

The implementation replaces the current workspace-scoped Directory endpoints with workspace-scoped Project endpoints:

```text
GET    /api/v1/workspaces/:workspaceId/projects
POST   /api/v1/workspaces/:workspaceId/projects
GET    /api/v1/workspaces/:workspaceId/projects/:projectId
PATCH  /api/v1/workspaces/:workspaceId/projects/:projectId
DELETE /api/v1/workspaces/:workspaceId/projects/:projectId
GET    /api/v1/workspaces/:workspaceId/projects/:projectId/files
GET    /api/v1/workspaces/:workspaceId/projects/:projectId/files/content
GET    /api/v1/workspaces/:workspaceId/projects/:projectId/reviews
GET    /api/v1/workspaces/:workspaceId/projects/:projectId/settings/access
PUT    /api/v1/workspaces/:workspaceId/projects/:projectId/settings/access
DELETE /api/v1/workspaces/:workspaceId/projects/:projectId/settings/access/:memberId
```

The Web Explorer changes from Directory list/detail state to Project list/detail state. Project detail contains Files, Reviews, and Settings. Generic filesystem “directory” terminology, machine folder pickers, and organization-directory/SSO APIs are not renamed.

Desktop MCP tools are renamed/replaced only for the saved resource contract (`directory_list`, `directory_add`, `directory_delete`); generic filesystem tools remain unchanged.

## Review association

- Existing Review snapshot/fingerprint/diff behavior from main, including PR #2702, is retained.
- This work adds `project_id`; it does not replace or redesign the Review fingerprint implementation.
- Review creation resolves/ensures the Project using authenticated workspace/machine authority and the selected root, then persists `project_id` with the Review.
- Browser and feedback routes authorize Review content through the associated Project after cutover.
- Compatibility columns remain until the Project read/write path is verified; destructive cleanup is a later, separately approved migration.

## Implementation sequence

### 1. Schema and read-only preflight

- Add `projects`, `project_grants`, and nullable `review_contexts.project_id` in one final-form migration.
- Copy existing Directory rows and backfill matching Review rows.
- Add focused store models and migration tests.
- Do not change product routes yet.

### 2. Project store, grants, and APIs

- Implement Project CRUD, access checks, Files endpoints, and grant operations.
- Reuse the existing machine runtime for path selection and file reads.
- Add workspace/machine/owner/cross-workspace authorization tests.

### 3. Review association

- Make all Review producers write `project_id`.
- Switch Review reads and feedback authorization to Project access.
- Preserve existing Review fingerprint/snapshot contracts.

### 4. Web/Desktop replacement

- Replace Explorer Directory navigation, API types, components, state, tests, and user-facing saved-resource copy with Project equivalents.
- Replace the three saved Directory MCP tools with Project tools.
- Keep generic directory browsing terminology where it refers to actual filesystem folders.

### 5. Final compatibility cleanup

- After the replacement path and backfill are verified, remove old Directory product routes/types/tools and then remove the `directories` table in the final migration.
- Compress migrations and commits before merge so the PR shows one forward path, not intermediate create/drop experiments.

## Verification and merge gates

- `origin/main...HEAD` must contain no unapproved permanent tables.
- Migration/bootstrap schemas must match.
- Real TiDB migration tests cover non-empty Directory data and Review backfill.
- Backend, Desktop, Web typecheck/tests, browser smoke, and `git diff --check` pass.
- Reviewer2 independently checks schema, data preservation, transactions, and authorization.
- GL2 independently checks product scope, Directory-vs-filesystem naming boundaries, Desktop/Web replacement, and test realism.
- No implementation task starts until this cleaned plan and inventory receive both approvals.
