Repository Public MIT
1# Implementation plan23Last updated: 2026-11-10. Scope reference: `docs/SPEC.md`.45Status labels used everywhere in this file:67- **Implemented + tested** — code exists and automated tests in `tests/` exercise it.8- **Implemented** — code exists; no dedicated automated test yet.9- **Planned** — not built. Nothing in the product may claim it.10- Rows updated on 2026-11-09 after the first production deployment (commit history has the details).1112Nothing here is "live" until the deployment row of the acceptance table is filled in.1314## Phase 0 — Discovery and design1516| Item | Status | Where |17|---|---|---|18| Hosting constraints inspected (MacLustr, `mld`, tunnel, PostgreSQL 17 on node) | Implemented | `docs/OPERATIONS.md` |19| Official standards checked (Agent Skills, MCP 2026-07-28, Claude Code, Codex, Cursor) | Implemented | `docs/STANDARDS.md` |20| Architecture decision records | Implemented | `docs/adr/0001`–`0009` |21| Data model | Implemented + tested | `packages/db/migrations/0001_init.sql` |22| Threat model | Implemented | `docs/THREAT_MODEL.md` |23| Permission matrix | Implemented | `docs/PERMISSIONS.md` |24| Visual system (tokens in `globals.css`; no separate wireframes were drawn) | Implemented | `apps/web` |25| Inventory of the owner's existing packages | Planned | none published without approval |2627## Phase 1 — Working public registry2829| Item | Status | Where |30|---|---|---|31| PostgreSQL schema, forward-only checksummed migrations | Implemented + tested | `packages/db` |32| Content-addressed blob storage, read-only blobs | Implemented + tested | `apps/web/src/server/storage.ts`, `publish.test.ts` |33| Read API: list, filter, search, categories, collections, artifact, versions, release detail, files, install instructions, checksum, download | Implemented + tested | `apps/web/src/server/api.ts`, `publish.test.ts` |34| Usage examples: screenshots listed in the manifest (`examples`, up to 8, PNG/JPEG/WebP checked by header, 1.5 MiB each), served only from the release archive by `GET …/versions/:version/media/*path`, shown on the artifact page (grouped by client, full-size dialog) | Implemented + tested | `packages/registry-core/src/media.ts`, `validate.ts`, `apps/web/src/server/media.ts`, `components/examples-gallery.tsx`; `core.test.ts` "usage examples", `publish.test.ts` "usage examples", `tests/e2e/examples.spec.ts` |35| Full-text search (tsvector, prefix, trigram fallback for queries of 5+ characters) | Implemented + tested | `registry.ts` |36| Semantic search | Planned | only with a measured relevance gain |37| OpenAPI 3.1 document generated from the route table | Implemented + tested | `GET /api/v1/openapi.json` |38| Download counting (daily aggregate, deduplicated, bot-filtered) | Implemented + tested | `publish.ts` |39| Homepage, explore, artifact pages, publisher profile, collections pages | Implemented + tested (E2E) | `apps/web/src/app` |40| Public docs and legal pages (content) | Implemented | `apps/web/content` |41| English UI with strings structured for French (`src/lib/i18n.ts`; many page strings are still inline) | Implemented | French translation itself is Planned |42| Demo seed data | Not applicable | no seed exists; production starts empty apart from real published artifacts |4344## Phase 2 — Authenticated publishing4546| Item | Status | Where |47|---|---|---|48| Owner bootstrap, local console only, fails closed | Implemented + tested | `auth.ts` `bootstrapOwner`, `tokens.test.ts` |49| Single-owner database constraint | Implemented + tested | `users_single_owner` index |50| Email + password login (argon2id), database sessions, CSRF for cookie writes | Implemented + tested | `auth.ts`, `api.ts` |51| Step-up re-authentication (15 minutes) for token creation and rotation | Implemented + tested | `tokens.test.ts` |52| Scoped API tokens: create, list, revoke, rotate, expiry, namespaces, IP allowlist | Implemented + tested | `auth.ts`, `tokens.test.ts` |53| Elevated tokens (administrators only, 24 hours maximum) | Implemented + tested | `tokens.test.ts` |54| Namespace ownership checks on every write | Implemented + tested | `publish.test.ts` "namespace isolation" |55| Upload flow: begin, PUT bytes, finalize | Implemented + tested | `publish.ts` |56| Archive validation and static scanning | Implemented + tested | `packages/registry-core`, `core.test.ts` |57| Immutable releases (database triggers), revocation state | Implemented + tested | migration `0001`, `publish.test.ts` |58| Quarantine and moderator review | Implemented + tested | `publish.ts` `reviewRelease` |59| Idempotency keys | Implemented + tested | `api.ts` |60| Append-only audit log with secret redaction | Implemented + tested | `audit.ts`, `tokens.test.ts` |61| Rate limiting and authentication-failure lockout | Implemented + tested | `ratelimit.ts`, `tokens.test.ts` |62| Server console (`pnpm admin …`) | Implemented | `apps/web/scripts/admin.ts` (services tested; the script wrapper is not) |63| CLI validate / pack / publish / dry-run | Implemented + tested (`tests/integration/cli.test.ts`) | `packages/cli` |64| Publisher dashboard (artifacts, browser upload, tokens, audit, moderation, account) | Implemented + tested (`tests/e2e/publisher.spec.ts`) | `apps/web` |65| Passkeys, OAuth sign-in, TOTP | Planned | `auth_identities` table exists for it |66| Self-service sign-up and email verification by mail | Planned | accounts are created by the operator |67| Per-namespace storage quotas | Planned | per-archive limits are enforced |68| Malware scanning (signature based) | Planned | static pattern scanner only |6970## Phase 3 — Agent integration7172| Item | Status | Where |73|---|---|---|74| Install adapters (instructions and config snippets) for Claude Code, Codex, Cursor, generic Skills, generic MCP | Implemented + tested | `packages/registry-core/src/install.ts`, `core.test.ts` |75| Typed SDK | Implemented | `packages/sdk` (typechecked; exercised through CLI tests when they land) |76| Registry MCP server (Streamable HTTP tested with the official client; stdio entry implemented, not covered by a test) | Implemented + tested (`tests/integration/mcp.test.ts`) | `apps/registry-mcp` |77| CLI install / update / download with checksum verification and rollback copy | Implemented + tested (`cli.test.ts`) | `packages/cli` |78| Example artifacts (published in production as `@spboucher/hello-skill`, `citation-check`, `echo-mcp-server`) | Implemented + tested | `examples/` |79| OAuth 2.1 authorization for the MCP endpoint | Planned | static bearer tokens in V1 |80| CLI published to npm with reproducible build provenance | Planned | runs from the repository in V1 |8182## Phase 4 — Community and trust8384| Item | Status | Where |85|---|---|---|86| Abuse reports without an account | Implemented + tested | `community.ts`, `publish.test.ts` |87| Moderation: takedown, restore, source verification, report resolution | Implemented + tested (verify-source, listing); Implemented (takedown, restore, resolve) | `community.ts` |88| Identity-verified namespaces | Implemented | set by the operator: `pnpm admin verify-namespace` |89| Editorial collections | Implemented | `community.ts`, `pnpm admin collections seed` |90| Organizations and memberships | Schema + authorization check only | no management surface; see `docs/PERMISSIONS.md` |91| Reviewer role | Schema only | grants nothing in V1 |92| Security advisories | Schema only | `security_advisories` table |93| Ownership transfers | Schema only | `ownership_transfers` table |94| Webhooks | Schema only | `webhooks`, `webhook_deliveries` tables |95| Appeals workflow | Planned | handled by email in V1 |96| Signed release metadata / provenance attestations | Planned | SHA-256 checksums always present |9798## Phase 5 — Research-grade extensions99100| Item | Status |101|---|---|102| Evaluation-kit type, bundle type with locked dependency versions | Implemented + tested (type and validation rules) |103| Structured benchmark metadata, workflow graphs | Planned |104| Federated registry discovery | Planned |105106## Acceptance criteria (spec section 18)107108| # | Criterion | Status | Evidence |109|---|---|---|---|110| 1 | A visitor can discover and inspect public Skills and MCP entries without signing in | Implemented + tested; verified in production 2026-11-09 (30 read-only E2E checks, desktop + mobile) | `tests/integration/publish.test.ts` "lets an anonymous visitor discover, inspect and download it" |111| 2 | A visitor can download a release and independently verify its SHA-256 | Implemented + tested | `publish.test.ts` (download hash equals metadata, `X-Checksum-Sha256`, `/checksum`) |112| 3 | Accurate, tested installation instructions for Claude Code and one other client | Implemented + tested. `skills install` into the Claude Code and Codex skill directories verified against production with a scratch HOME; MCP snippets are generated and unit-tested but were not executed inside each third-party client | `tests/unit/core.test.ts` "install adapters"; `publish.test.ts` "serves tested install instructions" |113| 4 | Secure owner bootstrap without a committed credential | Implemented + tested; run in production 2026-11-09 (`admin.bootstrap` audit event; password delivered to a 0600 file, never printed) | `tests/integration/tokens.test.ts` "owner bootstrap" |114| 5 | Issue a scoped Claude Code token, store it securely, publish, rotate, revoke | Implemented + tested; in production the token was piped from the server console into the macOS Keychain without being displayed, used to publish, rotated, and a probe token was revoked (401 `token_revoked`) | `tokens.test.ts` "scoped API tokens" |115| 6 | Revoked or expired token cannot publish; no cross-namespace modification | Implemented + tested | `tokens.test.ts` "a revoked token cannot publish", "an expired token cannot publish"; `publish.test.ts` "namespace isolation" |116| 7 | Claude Code can validate, dry-run, upload, publish and verify via CLI/API | Implemented + tested (`cli.test.ts`); done in production for the three examples (dry run, publish, re-download and re-hash) | `publish.test.ts` "vertical slice" |117| 8 | Public MCP can search and inspect; publishing tools need authentication | Implemented + tested; verified in production with the official MCP client (12 tools, anonymous write → 401, traversal → 400) | `tests/integration/mcp.test.ts` |118| 9 | Malicious archive cannot traverse paths, expose secrets, execute on ingestion or overwrite another package | Implemented + tested | `core.test.ts` "tar codec", "path safety", "static scanner"; `publish.test.ts` "hostile uploads" |119| 10 | Releases are immutable and their history auditable | Implemented + tested | `publish.test.ts` "refuses to republish or mutate an existing version", "publishes a new version and moves latest, keeping history" |120| 11 | Unit, integration and E2E tests pass; accessibility and mobile QA pass | Unit + integration: 108 passing. E2E: 38 passing locally (desktop + Pixel 7 viewport), including axe WCAG 2.1 A/AA on 8 public pages and the token page, and no horizontal overflow. Not covered: manual screen-reader pass, real iOS Safari | `pnpm test` |121| 12 | Docs, backups, monitoring, incident response, security contact present | Implemented. Daily backup at 04:50 (PM2 `skills-maint`) and restore drill run on 2026-11-09 (`infra/restore-drill.sh`). Monitoring is health endpoints + `mld heal`; no external uptime monitor or alerting yet | `docs/OPERATIONS.md`, `SECURITY.md` |122| 13 | Production deployed at https://skills.spboucher.ai after DNS, TLS, secrets and approval | Deployed 2026-11-09 on M3U96b via `mld` (owner asked for the deployment and had set DNS; Let's Encrypt certificate through the Caddy gateway) | `mld status`, `/api/v1/health/ready` |123124## Known limitations125126- Single process. Rate limits and the authentication-failure lockout live in process memory; they reset on restart and do not coordinate across instances (ADR-0004).127- Blobs are on the node's filesystem, not in S3-compatible storage (ADR-0003). Durability depends on the backup job.128- The scanner is a static pattern matcher. It does not detect obfuscated malware and makes no safety guarantee.129- No email is sent. There is no self-service sign-up, password-reset mail or email verification by link; the operator creates accounts and resets passwords from the server console, and the bootstrap marks the owner's email as operator-attested.130- No second factor in V1.131- Organizations exist in the schema and in the authorization check, but cannot be created or managed through any interface.132- `compatibility` entries are publisher claims. The `verified` flag exists but nothing sets it yet.133- The whole archive is buffered in memory during finalize (20 MiB cap).134- Example images are read by unpacking the release archive in memory on first request, then kept in a per-process cache (96 MiB cap). Only image headers are checked; images are not decoded, re-encoded or resized, so the page loads them at full size.135- No CI pipeline yet; checks are run locally and at deploy.136- Docker Compose for local development is not provided; local development uses a local PostgreSQL.137138## Next milestones1391401. Done 2026-11-09: CLI, MCP server and web UI landed and the rows above carry their evidence.1412. Deploy, run the bootstrap, issue the publisher token, publish the example artifacts with the owner's approval, verify criteria 1–13 against production.1423. CI (typecheck, tests, dependency audit, secret scan).1434. TOTP and passkeys for human accounts; self-service sign-up with email verification.1445. OAuth 2.1 for the MCP endpoint.1456. Organization management, ownership transfers, webhooks, advisories.1467. S3-compatible storage driver and off-site blob replication.147