> ## Documentation Index
> Fetch the complete documentation index at: https://aipkg.org/llms.txt
> Use this file to discover all available pages before exploring further.

# Migration Plan

> Phased migration from NuGetGallery to AI•Pkg — four phases from clean solution foundation through CLI MVP, with source file mapping, deletion lists, and verification checklists.

The AI•Pkg server is built by forking NuGetGallery, stripping everything that doesn't translate to the AI plugin registry use case, and building the AI•Pkg-specific surface on top. The migration is structured into four phases so that core infrastructure (Phases 0–1) can be verified independently before UI (Phase 3) and CLI (Phase 4) work begins.

<Warning>
  The existing `NuGetGallery.sln` (139 projects) is **not** converted. A new `AI•Pkg.slnx` is created from scratch, pulling in only the source files and projects that are being retained.
</Warning>

***

## Pre-Migration: Fork Setup

<Steps>
  <Step title="Fork the repo">
    Fork `NuGet/NuGetGallery` → `AI•Pkg/AIpkgGallery` on GitHub.
  </Step>

  <Step title="Create dev branch">
    Create a `dev` branch from `main` for migration work.
  </Step>

  <Step title="Protect main">
    Do **not** push breaking changes to `main` until Phase 1 is complete and tested.
  </Step>

  <Step title="Add specs">
    Add the `src/AI•Pkg.Docs/` directory to the fork (already done).
  </Step>
</Steps>

***

## Phase 0: Clean Solution Foundation

**Goal:** A buildable ASP.NET Core 10 SLNX solution with SQL Server DB Project and EasyAF scaffolding, no legacy code.

### Step 0.1: Create `AI•Pkg.slnx`

Create a new Visual Studio SLNX solution file at the repo root. Add projects incrementally as they are created.

### Step 0.2: Create Core Projects

| Project                      | Type                               | Notes                       |
| ---------------------------- | ---------------------------------- | --------------------------- |
| `src/AI•Pkg.Core/`           | .NET 10 class library              | No NuGet output yet         |
| `src/AI•Pkg.Server/`         | ASP.NET Core 10 web app            | Minimal APIs + Blazor       |
| `src/AI•Pkg.Server.Db/`      | SQL Server DB Project (`.sqlproj`) | Schema source of truth      |
| `src/AI•Pkg.Server.Data/`    | .NET 10 class library              | EasyAF-generated; committed |
| `tests/AI•Pkg.Core.Tests/`   | xUnit .NET 10                      |                             |
| `tests/AI•Pkg.Server.Tests/` | xUnit .NET 10                      |                             |

### Step 0.3: Set Up SQL Server Database Project

| NuGetGallery source   | AI•Pkg table          | Changes                                                                                                                                        |
| --------------------- | --------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------- |
| `Packages`            | `Packages`            | Remove: `RequiresLicenseAcceptance`, `DevelopmentDependency`, `IsSymbolsPackage`. Add: `Capabilities`, `Targets`, `Permissions` (JSON columns) |
| `PackageVersions`     | `PackageVersions`     | Same as above; keep download count                                                                                                             |
| `PackageOwners`       | `PackageOwners`       | No change                                                                                                                                      |
| `Users`               | `Users`               | Keep; remove legacy OpenID fields                                                                                                              |
| `Credentials`         | `Credentials`         | Keep PBKDF2 API key structure                                                                                                                  |
| `PackageDependencies` | `PackageDependencies` | Add `Apms` column (JSON) instead of `TargetFramework`                                                                                          |
| `PackageTags`         | `PackageTags`         | No change                                                                                                                                      |
| `PackageHistories`    | `PackageHistories`    | No change                                                                                                                                      |
| `PackageRenames`      | *(drop)*              | Not needed                                                                                                                                     |
| `SymbolPackages`      | *(drop)*              | Not applicable                                                                                                                                 |

### Step 0.4: EasyAF Code Generation

Run EasyAF CLI against `AI•Pkg.Server.Db/` to generate:

* EF Core 10 entity classes → `AI•Pkg.Server.Data/Entities/`
* Repository classes → `AI•Pkg.Server.Data/Repositories/`
* `AIpkgDbContext.cs` → `AI•Pkg.Server.Data/`

Generated files are committed to the repo and regenerated whenever the DB project changes.

### Phase 0 Verification

* [ ] `dotnet build AI•Pkg.slnx` succeeds with zero errors
* [ ] `dotnet test` on `AI•Pkg.Core.Tests` and `AI•Pkg.Server.Tests` passes
* [ ] DB project publishes successfully to a local SQL Server instance
* [ ] EasyAF-generated entities compile against the DB project schema

***

## Phase 1: Core Registry API + Auth + AI•Pkg.Core

**Goal:** Working push, download, registration, and authentication. Package round-trip: `aipkg pack` → `aipkg push` → `aipkg install`.

### Source Files to Port

| Source file                                                         | Destination                                            | Action                                                       |
| ------------------------------------------------------------------- | ------------------------------------------------------ | ------------------------------------------------------------ |
| `src/NuGet.Services.Entities/Package.cs`                            | `AI•Pkg.Server.Data/Entities/Package.cs`               | Generated by EasyAF; use as reference for field list         |
| `src/NuGetGallery.Core/Packaging/PackageMetadata.cs`                | `AI•Pkg.Core/Packaging/ManifestReader.cs`              | Port pattern; replace XML with `System.Text.Json`            |
| `src/NuGetGallery.Core/Frameworks/FrameworkCompatibilityService.cs` | `AI•Pkg.Core/Platform/PlatformCompatibilityService.cs` | Port architecture; replace TFM logic with APM fallback graph |
| `src/NuGetGallery/Controllers/ApiController.cs` (V3 parts)          | `AI•Pkg.Server/Api/V3/`                                | Port push/delete/autocomplete as Minimal APIs                |
| `src/NuGet.Jobs.Catalog2Registration/Schema/EntityBuilder.cs`       | `AI•Pkg.Server/Jobs/RegistrationBuilder.cs`            | Port; update JSON-LD schema for AI•Pkg fields                |
| `src/NuGetGallery/Services/PackageService.cs`                       | `AI•Pkg.Server/Services/PackageService.cs`             | Port; strip symbol/V2 logic                                  |
| `src/NuGetGallery/Services/UserService.cs`                          | `AI•Pkg.Server/Services/UserService.cs`                | Port PBKDF2 API key management                               |
| `src/NuGetGallery/Authentication/`                                  | `AI•Pkg.Server/Auth/`                                  | Port GitHub OAuth + API key auth                             |
| `src/NuGetGallery.Core/Services/CorePackageFileService.cs`          | `AI•Pkg.Server/Storage/PackageStorageService.cs`       | Port; rename `.nupkg` → `.aipkg`                             |

### Step 1.1: AI•Pkg.Core Implementation Order

<Steps>
  <Step title="AipkgManifest model">
    Implement `AipkgManifest` model with `System.Text.Json` source-gen serialization.
  </Step>

  <Step title="AipkgReader">
    ZIP reading and manifest extraction.
  </Step>

  <Step title="AipkgWriter">
    ZIP creation.
  </Step>

  <Step title="PlatformCompatibilityService">
    APM fallback graph (hardcoded table for now).
  </Step>

  <Step title="AipkgValidator">
    Manifest validation + archive validation.
  </Step>

  <Step title="AipkgVersion">
    SemVer parsing and range checking.
  </Step>
</Steps>

Write unit tests for each in `AI•Pkg.Core.Tests`.

### Step 1.2: Registry API Endpoints

Implement Minimal API endpoints in `AI•Pkg.Server/Api/V3/`:

```
GET  /v3/index.json
GET  /v3/registration/{id}/index.json
GET  /v3/registration/{id}/{version}.json
GET  /v3/flatcontainer/{id}/index.json
GET  /v3/flatcontainer/{id}/{version}/{id}.{version}.aipkg
GET  /v3/flatcontainer/{id}/{version}/{id}.{version}.aispec
PUT  /v3/package
DELETE /v3/package/{id}/{version}
GET  /v3/platforms
GET  /v3/registration/{id}/{version}/install/{apm}
```

<Note>
  Search and autocomplete endpoints are added in Phase 2 (they depend on Azure AI Search).
</Note>

### Phase 1 Verification

* [ ] `aipkg pack {id}.aispec` produces a valid `{id}.{version}.aipkg`
* [ ] `aipkg push {package}.aipkg` succeeds against a local server instance
* [ ] `GET /v3/flatcontainer/{id}/{version}/{id}.{version}.aipkg` returns the uploaded package
* [ ] `GET /v3/registration/{id}/index.json` returns valid registration data
* [ ] `aipkg verify {package}.aipkg` exits 0 for a valid package, 1 for invalid
* [ ] API key auth blocks unauthorized pushes with 401

***

## Phase 2: Search + Catalog Pipeline

**Goal:** Functional search and autocomplete. Packages appear in search results after push.

### Source Files to Port

| Source                                                          | Destination                                   | Action                                     |
| --------------------------------------------------------------- | --------------------------------------------- | ------------------------------------------ |
| `src/NuGet.Services.AzureSearch/Models/BaseMetadataDocument.cs` | `AI•Pkg.Server.Search/AipkgSearchDocument.cs` | Port structure; adapt fields               |
| `src/NuGet.Services.AzureSearch/` (indexing pipeline)           | `AI•Pkg.Server.Search/`                       | Port; use `AipkgSearchDocument`            |
| `src/Stats.*`                                                   | `src/AI•Pkg.Jobs/Stats/`                      | Port CDN stats parsing; adapt for `.aipkg` |
| `src/GitHubVulnerabilities2Db/`                                 | `src/AI•Pkg.Jobs/Vulnerabilities/`            | Port; adapt package ID resolution          |

### Phase 2 Verification

* [ ] Pushing a package makes it appear in `GET /v3/search?q={id}` within 60 seconds
* [ ] `GET /v3/search?apm=claude-code` returns only claude-compatible packages
* [ ] `GET /v3/search?capability=mcp-server` filters correctly
* [ ] `GET /v3/autocomplete?q={prefix}` returns matching package IDs
* [ ] Download count increments after each package download (within stats job cycle)

***

## Phase 3: Blazor Web UI

**Goal:** Full public-facing web UI. Users can browse, search, view packages, upload, and manage accounts via browser.

Build all Blazor components as defined in [Registry UI spec](../specs/11-registry-ui). No porting of Razor views — build fresh.

Implementation order:

1. Layout components (NavBar, Footer, MainLayout)
2. Package detail page (most important for discoverability)
3. Search / browse pages
4. Home page
5. Upload wizard
6. Account / API key management
7. Admin panel

### Phase 3 Verification

* [ ] Home page loads and shows featured/new packages
* [ ] Search returns results with correct filtering by APM and capability
* [ ] Package detail page shows README, manifest, version history
* [ ] Version selector switches versions without full page reload
* [ ] Upload wizard accepts a valid `.aipkg` and publishes successfully
* [ ] API key management allows create/revoke
* [ ] All public SSR pages score ≥90 on Lighthouse SEO and Performance
* [ ] WCAG 2.1 AA automated checks pass

***

## Phase 4: `aipkg` CLI MVP

**Goal:** Functional install, restore, remove, list, search commands. Single-binary Native AOT release.

Add remaining CLI commands (see [SDK Interface spec](../specs/10-sdk-interface)):
`install`, `restore`, `remove`, `list`, `search`, `info`, `sources`, `new`, `login`, `logout`

Configure Native AOT publishing pipeline in GitHub Actions. Publish to GitHub Releases.

### Phase 4 Verification

* [ ] `aipkg install git-helpers` downloads, extracts, and installs to `.claude/` (on claude-code)
* [ ] `aipkg restore` installs all packages from `aipkg.config.json`
* [ ] `aipkg.lock.json` is written with correct hashes and resolved versions
* [ ] `aipkg remove git-helpers` cleans up installed files
* [ ] `aipkg search mcp` returns results from aipkg.org
* [ ] Native AOT binary runs on Windows, macOS, Linux without .NET runtime installed
* [ ] Binary size \< 30 MB per platform

***

## What to Delete from NuGetGallery

### Entire Projects / Directories

| Path                               | Reason                                               |
| ---------------------------------- | ---------------------------------------------------- |
| `src/NuGetGallery/` (old MVC app)  | Replaced by `AI•Pkg.Server/`                         |
| `src/NuGetGallery.Core/`           | Replaced by `AI•Pkg.Core/` + `AI•Pkg.Server.*`       |
| `src/NuGet.Services.Entities/`     | Replaced by EasyAF-generated entities                |
| `src/NuGet.Services.Odata/`        | V2 OData — not used                                  |
| `src/NuGetGallery.WebUITests/`     | Old Selenium tests — not used                        |
| `src/NuGet.Jobs.Symbols*/`         | Symbol package infrastructure — not applicable       |
| `src/NuGet.Services.Logging/`      | Replace with `Microsoft.Extensions.Logging` directly |
| `tests/NuGetGallery.Core.Facts/`   | Recreate in `AI•Pkg.Core.Tests/`                     |
| `tests/NuGetGallery.Facts/`        | Recreate in `AI•Pkg.Server.Tests/`                   |
| `NuGetGallery.FunctionalTests.sln` | Not migrated                                         |
| `tools/` (Python tooling)          | Python scripts — not used                            |

### Files Within Retained Projects

| File/Pattern                           | Reason                                  |
| -------------------------------------- | --------------------------------------- |
| `**/*.cshtml`                          | All Razor views — replaced by Blazor    |
| `**/_ViewImports.cshtml`               | Razor infrastructure                    |
| `**/BundleConfig.js`                   | jQuery bundling                         |
| `**/Startup.cs` (OWIN)                 | OWIN startup — replaced by `Program.cs` |
| `**/Global.asax*`                      | OWIN/System.Web                         |
| `src/NuGetGallery/OData/`              | V2 OData controllers                    |
| `src/NuGetGallery/Controllers/ODataV*` | V2 OData controllers                    |
| `**/AutofacRegistration*.cs`           | Autofac modules                         |
| `**/ContainerBindings.cs`              | Autofac container setup                 |
| `**/packages.config`                   | Old-style NuGet package references      |

***

## Project Rename Reference

| Original                     | New                                          |
| ---------------------------- | -------------------------------------------- |
| `NuGetGallery`               | `AI•Pkg.Server`                              |
| `NuGetGallery.Core`          | `AI•Pkg.Core`                                |
| `NuGet.Services.Entities`    | `AI•Pkg.Server.Data` (generated)             |
| `NuGet.Services.AzureSearch` | `AI•Pkg.Server.Search`                       |
| `NuGetGallery.Core.Facts`    | `AI•Pkg.Core.Tests`                          |
| `NuGetGallery.Facts`         | `AI•Pkg.Server.Tests`                        |
| `Stats.*`                    | `AI•Pkg.Jobs` (combined jobs project)        |
| `GitHubVulnerabilities2Db`   | part of `AI•Pkg.Jobs`                        |
| `NuGet.Packaging` (client)   | `AI•Pkg.Core` (implements own reader/writer) |
| `NuGetGallery.sln`           | `AI•Pkg.slnx`                                |

***

## Critical Source Files to Reference

Read these NuGetGallery files before implementing the corresponding AI•Pkg components:

| NuGetGallery source                                                 | AI•Pkg component                                       | What to learn                    |
| ------------------------------------------------------------------- | ------------------------------------------------------ | -------------------------------- |
| `src/NuGet.Services.Entities/Package.cs`                            | `AI•Pkg.Server.Data/Entities/Package.cs`               | Entity field list, relationships |
| `src/NuGetGallery.Core/Frameworks/FrameworkCompatibilityService.cs` | `AI•Pkg.Core/Platform/PlatformCompatibilityService.cs` | Fallback graph algorithm         |
| `src/NuGet.Services.AzureSearch/Models/BaseMetadataDocument.cs`     | `AI•Pkg.Server.Search/AipkgSearchDocument.cs`          | Search document field design     |
| `src/NuGet.Jobs.Catalog2Registration/Schema/EntityBuilder.cs`       | `AI•Pkg.Server/Jobs/RegistrationBuilder.cs`            | Registration blob construction   |
| `src/NuGetGallery.Core/Packaging/PackageMetadata.cs`                | `AI•Pkg.Core/Packaging/ManifestReader.cs`              | Manifest parsing patterns        |
| `src/Stats.*/`                                                      | `AI•Pkg.Jobs/Stats/`                                   | CDN log parsing                  |
| `src/GitHubVulnerabilities2Db/`                                     | `AI•Pkg.Jobs/Vulnerabilities/`                         | Vulnerability job pattern        |

***

## Open Items / Lower Priority

| Item                             | Notes                                                                              |
| -------------------------------- | ---------------------------------------------------------------------------------- |
| License scanning                 | Evaluate porting `NuGet.Jobs.Validation.PackageSigning.*`; lower priority          |
| Package signing                  | Spec defined in [Code Signing spec](../specs/05-code-signing); implement post-MVP  |
| OIDC auth provider               | Post-MVP; add alongside GitHub OAuth                                               |
| TypeScript SDK                   | `@aipkg/core` etc.; post-MVP (see [SDK Interface spec](../specs/10-sdk-interface)) |
| `@aipkg/claude-code` npm package | Post-MVP                                                                           |
| DotNetDocs.com integration       | Begin after `AI•Pkg.Core` 1.0.0 stabilizes                                         |
| Package verified badges          | Need author verification system design                                             |
| A/B testing framework            | Post-MVP                                                                           |
