Implementation Plan: Project Works (EW-P2-4)
Spec: spec.md · Branch: feat/gw-project-work-kind
Additive only; today's behaviour is the default; the kind ships dormant behind EVER_WORKS_PROJECT_WORKS_ENABLED.
No migration: works.kind is varchar(32) with no CHECK constraint, so a new value needs no schema change.
- Contracts —
WORK_KINDS(+projectbeforedefault),isProjectWorkKind,WORK_KIND_CAPABILITIES.project(every repository role off),workKindHasRepository. Pinned tests updated (domain.spec,work-capabilities.spec, the docs-parity spec viadocs/features/work-kinds.md). - Switch —
config.everWorks.projectWorks.enabled(),apps/api/.env.example, the CI default-off scanner. - Create —
WorkLifecycleService.createProjectWork(bare row, refuses when off) +WorkProjectsController(POST /api/works/projects, slug resolution throughcheckSlugAvailability). - Guards —
assertNotRepositoryWorkrefusesprojecttoo (one place, every pipeline entry point). - Tasks —
resolveTaskRepository→TaskRepositoryTarget | null;kindHasTaskRepository,requireTaskRepository,pickOwnerRepo; every caller handles none (run → no workspace, fleet →null, merge / branch GC → skip, PR / review / release / App gates →requireTaskRepository); agent git tools refuse. - List —
findAllAccessible/countAllAccessible/getWorkstakekind;GET /api/works?kind=. - Web — presentation entry + i18n label (21 locales). The
Record<WorkKind, …>makes the entry compile-required. - Tests — contracts, guard, task repository, workspace run path, create (switch on/off), controller (create, list filter), agent git tool refusal; full agent / api / contracts / web suites before merge.