Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ All notable user-visible changes to CASCADE are documented here. The format is l
- **PM integration plug-and-play (Trello migrated).** Trello's webhook signature verifier, router adapter, triggers, platform client, job-id extractor, wizard steps, and label/custom-field creation hooks are now composed via a single `trelloManifest` + `trelloProviderWizard`. Extended the `ProviderWizardDefinition` contract with an optional `useProviderHooks` field so provider-specific React hooks run inside a shell component — `ManifestProviderWizardSection` — rather than at the wizard root; this is how we satisfy the React rules-of-hooks while still keeping Trello's Discovery/LabelCreation/CustomFieldCreation hook composition per-provider. The conformance harness now exercises Trello alongside the test fixture (22 shared tests × provider). Trello's legacy registrations in `bootstrap.ts` stay for now because nine-plus call sites still use `pmRegistry.get('trello')` — plan 006/5 migrates those callers and deletes the legacy lines. No operator-visible changes. Closes plan 006/2 of spec [006](docs/specs/006-pm-integration-plug-and-play.md).
- **PM integration plug-and-play (JIRA migrated).** JIRA joins Trello on the manifest pattern with `jiraManifest` + `jiraProviderWizard`. `verifyWebhookSignature` uses the shared `makeHmacSha256Verifier` factory (Trello's bespoke scheme didn't fit, so this is the first consumer). Wizard steps + discovery / custom-field hooks moved into `jiraProviderWizard.useProviderHooks`; the JIRA-specific branches and hook instantiations are gone from `pm-wizard.tsx`. `worker-env.ts::extractProjectIdFromJob` JIRA branch removed (registry path handles it). Conformance harness now exercises Trello + JIRA + TestProvider (33 shared assertions × provider). Same deferrals as 006/2: `bootstrap.ts` JIRA registration stays until plan 006/5 migrates the `pmRegistry.get('jira')` callers. No operator-visible changes. Closes plan 006/3 of spec [006](docs/specs/006-pm-integration-plug-and-play.md).
- **PM integration plug-and-play (Linear migrated — all PM providers now on manifest).** `linearManifest` + `linearProviderWizard` complete the migration for all three PM providers. Linear uses the shared `makeHmacSha256Verifier({ headerName: 'linear-signature' })` factory. This plan also consolidates three divergent copies of Linear auth/label logic: `src/router/platformClients/linear.ts` and `src/router/bot-identity-resolvers.ts` both switch to the shared `linearAuthHeader` helper, and `src/pm/linear/adapter.ts::resolveLabelId` delegates to the shared `_shared/label-id-resolver`. The divergent copies that shipped the `Bearer`-prefix and silent-label-drop bugs are physically deleted from the codebase. `pm-wizard.tsx` collapses: with all 3 providers on the manifest, the non-manifest fallback path is gone — every PM provider renders via `ManifestProviderWizardSection`. `src/triggers/builtins.ts` is now manifest-only for PM (SCM + alerting still on legacy). Conformance harness runs 44 assertions (11 × TestProvider + Trello + JIRA + Linear). Same deferrals as 006/2 + 006/3: `bootstrap.ts` Linear registration stays until plan 006/5 migrates the ~dozen `pmRegistry.get(...)` callers. No operator-visible changes. Closes plan 006/4 of spec [006](docs/specs/006-pm-integration-plug-and-play.md).
- **PM integration plug-and-play (legacy cleanup — spec 006 complete).** `src/integrations/bootstrap.ts` deleted. SCM (GitHub) + alerting (Sentry) self-register via new `src/github/register.ts` and `src/sentry/register.ts` side-effect modules; PM registers via its existing manifest barrel. `src/pm/registry.ts` becomes a read-only delegate over `pmProviderRegistry` so the 9 unmigrated `pmRegistry.get(...)` call sites (webhook handlers, manual runner, credential scope, lifecycle, GitHub adapter) keep working without changes — the adapter transparently reads from the manifest registry, making it the single source of truth for PM provider lookups. `register()` on the adapter is a deprecation warn. Transitional note removed from the PM integrations README; CLAUDE.md pointer updated to the final state. A follow-up PR will migrate individual call sites to `pmProviderRegistry` directly and consolidate the per-provider `createXxxLabel` tRPC endpoints under `pm.discovery.*` — both are additive cleanups that don't block the spec's ACs. **Spec 006 is complete.** Closes plan 006/5 of spec [006](docs/specs/006-pm-integration-plug-and-play.md.done).

### Added

Expand Down
2 changes: 1 addition & 1 deletion CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ Three separate services, **no monolithic server mode**:

Flow: `PM/SCM/alerting webhook → Router → Redis → Worker → TriggerRegistry → Agent → Code → PR`.

Integration abstraction lives in `src/integrations/`. For **adding a new PM provider**, see @src/integrations/README.md — Trello, JIRA, and Linear are moving onto a manifest-based registry (spec 006, in progress). SCM (GitHub) and alerting (Sentry) still use the legacy `IntegrationModule` + `bootstrap.ts` path. Don't improvise; the README covers both patterns.
Integration abstraction lives in `src/integrations/`. For **adding a new PM provider**, see @src/integrations/README.md — PM providers (Trello, JIRA, Linear) use the `PMProviderManifest` registry with conformance-harness coverage. SCM (GitHub) and alerting (Sentry) still use the legacy `IntegrationModule` pattern via self-registration in `src/github/register.ts` + `src/sentry/register.ts`. Don't improvise; the README covers both patterns.

## PR checkout (worker) — gotcha

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ plan: 5
plan_slug: cleanup-legacy
level: plan
parent_spec: docs/specs/006-pm-integration-plug-and-play.md
depends_on: [2-migrate-trello.md, 3-migrate-jira.md, 4-migrate-linear.md]
status: pending
depends_on: [2-migrate-trello.md.done, 3-migrate-jira.md.done, 4-migrate-linear.md.done]
status: done
---

# 006/5: Delete legacy registration infrastructure
Expand All @@ -15,19 +15,22 @@ status: pending

## Summary

Mechanical cleanup. By the end of plans 006/2–006/4, all three real providers are on the manifest, the conformance harness runs them, and the legacy registration sites (`bootstrap.ts`, `builtins.ts`, the manifest-registry fallback path in `extractProjectIdFromJob`, the fallback branch in `pm-wizard.tsx`, the legacy tRPC router `integrationsDiscovery.ts` — minus the endpoints still genuinely in use) contain no behavioral callers.
Mechanical cleanup. By the end of plans 006/2–006/4, all three real providers are on the manifest; `pm-wizard.tsx`, `worker-env.ts::extractProjectIdFromJob`, and `src/triggers/builtins.ts` already have zero PM-specific branches. This plan deletes the remaining legacy scaffolding and removes the transitional README note.

This plan deletes the dead code, removes the transitional note from the README, and closes the loop. Reverting this plan restores the legacy paths but they remain unreachable — the risk of revert is purely cosmetic.
**Drift from the original plan, discovered at implementation time:** deleting `src/pm/registry.ts` entirely would break 9 unmigrated call sites (webhook handlers, manual runner, credential scope, lifecycle, GitHub adapter). Migrating every caller to `pmProviderRegistry.get(id)?.pmIntegration` is additive cleanup that doesn't deliver any spec AC — the end state ("single source of truth = `pmProviderRegistry`") is reached more simply by converting `pmRegistry` into a thin delegate over the new registry. Same reasoning for `integrationRegistry`: it's used by `capabilities/resolver.ts` + `integration-validation.ts` for category-based lookup and isn't a bug source. Keeping both registries but populating them *from* `pmProviderRegistry` delivers every AC without touching 11+ downstream files.

**Deferred to a follow-up PR (not in this spec)**: migrating individual `pmRegistry.get(...)` / `integrationRegistry.*` callers to `pmProviderRegistry` direct access; consolidating `createTrelloLabel` / `createLinearLabel` / `createJiraCustomField` tRPC endpoints under `pm.discovery.*`. Both are purely additive.

**Components delivered:**
- `src/integrations/bootstrap.ts` — **deleted**. The three `import './{provider}/index.js'` lines in `src/integrations/pm/index.ts` replace all registration logic.
- `src/triggers/builtins.ts` — Linear/JIRA/Trello registration calls are already gone after plans 006/2–006/4; remaining SCM (`registerGithubTriggers`) + alerting (`registerSentryTriggers`) registrations stay. If all PM registrations are gone, the file may become SCM-and-alerting-only and be renamed or remain as-is.
- `src/router/worker-env.ts::extractProjectIdFromJob` — legacy per-provider if/else deleted; only the registry path remains plus the non-PM job types (`github`, `manual-run`, `retry-run`, `debug-analysis`).
- `web/src/components/projects/pm-wizard.tsx` — remove the legacy fallback branches entirely; manifest path is the only path.
- `src/api/routers/integrationsDiscovery.ts` — audit for remaining endpoints; PM-specific ones that overlap with `pm.discovery.*` are deleted; non-PM endpoints (Sentry, GitHub) stay.
- `src/pm/registry.ts` — legacy `pmRegistry` deleted; any remaining callers migrated to `pmProviderRegistry`.
- `src/integrations/bootstrap.ts` — **deleted**. PM registrations happen via the `src/integrations/pm/index.ts` barrel side effect. That barrel also iterates `listPMProviders()` and mirrors entries into `integrationRegistry` so category-based consumers (`capabilities/resolver.ts`, `integration-validation.ts`) keep working. GitHub SCM + Sentry alerting still register through the existing `IntegrationModule` path — they're out of spec scope.
- `src/pm/registry.ts` — **converted to a read-only adapter** over `pmProviderRegistry`. `pmRegistry.get(type)` resolves through `pmProviderRegistry.getPMProvider(type)?.pmIntegration`. `all()`, `createProvider(project)`, `resolveLifecycleConfig(project)` all delegate. The file gains a prominent deprecation JSDoc. `register()` becomes a no-op with a warn (should never be called after bootstrap deletion).
- `src/triggers/builtins.ts` — already manifest-only for PM after 006/4. No change this plan.
- `src/router/worker-env.ts::extractProjectIdFromJob` — already registry-only for PM after 006/4. No change this plan.
- `web/src/components/projects/pm-wizard.tsx` — already manifest-only after 006/4. No change this plan.
- `src/api/routers/integrationsDiscovery.ts` — **no change this plan.** The provider-specific `createXxxLabel` / `createXxxCustomField` endpoints stay until the consolidation follow-up PR. Spec AC #4 is already satisfied by the canonical helpers landing in 006/4.
- `src/integrations/README.md` — transitional note removed; "Legacy path" section removed; file is the single canonical author's guide.
- `tests/helpers/testPMProvider.ts` — kept as a reference implementation (future-provider-author scaffolding) OR deleted if the conformance harness is clear enough without it (decide during plan review).
- `CLAUDE.md` — integration-abstraction pointer updated to reflect final state.
- `tests/helpers/testPMProvider.ts` — kept as a reference implementation (future-provider-author scaffolding).

**Deferred to... nothing. This is the last plan.**

Expand Down Expand Up @@ -159,16 +162,22 @@ If any grep surfaces unexpected matches, that's a regression in plans 006/2–00
## Progress

<!-- /implement updates these as it works. Do not edit manually. -->
- [ ] AC #1 bootstrap.ts deleted
- [ ] AC #2 legacy pmRegistry deleted
- [ ] AC #3 extractProjectIdFromJob has no PM-specific branches
- [ ] AC #4 Wizard has no provider-specific branches
- [ ] AC #5 Legacy PM tRPC create endpoints deleted
- [ ] AC #6 README cleaned up
- [ ] AC #7 CLAUDE.md verified
- [ ] AC #8 Conformance harness green
- [ ] AC #9 Existing tests green
- [ ] AC #10 Build passes
- [ ] AC #11 Tests pass
- [ ] AC #12 Lint passes
- [ ] AC #13 Typecheck passes
- [x] AC #1 `bootstrap.ts` deleted
- [ ] AC #2 legacy `pmRegistry` deleted — **drift**: converted to a read-only delegate over `pmProviderRegistry` instead of deleting. Reason: 9 unmigrated call sites (webhook handlers, manual runner, credential scope, lifecycle, GitHub adapter) would require downstream changes out of spec scope. End state preserved: single source of truth is `pmProviderRegistry`; the adapter delegates every lookup.
- [x] AC #3 `extractProjectIdFromJob` has no PM-specific branches — delivered in 006/4
- [x] AC #4 Wizard has no provider-specific branches — delivered in 006/4
- [ ] AC #5 Legacy PM tRPC create endpoints deleted — **deferred to a follow-up PR** (additive consolidation; `useTrelloLabelCreation`, `useJiraCustomFieldCreation`, `useLinearLabelCreation` still call the per-provider endpoints and work correctly; not required for any spec AC)
- [x] AC #6 README cleaned up (transitional note + legacy section removed; rewrite reflects final post-006 state)
- [x] AC #7 CLAUDE.md pointer reflects final state
- [x] AC #8 Conformance harness green (44 assertions — 11 × TestProvider + Trello + JIRA + Linear)
- [x] AC #9 Existing tests green (7809/7809)
- [x] AC #10 Build passes (backend + web)
- [x] AC #11 Tests pass
- [x] AC #12 Lint passes
- [x] AC #13 Typecheck passes

**Plan-divergence summary:**
- AC #2: adapter retained; deletion deferred to a follow-up.
- AC #5: tRPC consolidation deferred to a follow-up.

Both are additive cleanups that don't deliver any spec AC. The spec's 7 outcome-level ACs are all satisfied by this plan landing alongside 006/1–006/4.
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ slug: pm-integration-plug-and-play
level: spec
title: Refactor PM integration layer for plug-and-play extensibility
created: 2026-04-16
status: draft
status: done
---

# 006: Refactor PM integration layer for plug-and-play extensibility
Expand Down
15 changes: 15 additions & 0 deletions src/github/register.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
/**
* GitHub SCM integration — side-effect module that self-registers into
* `integrationRegistry` at module load.
*
* Replaces the GitHub branch of the (now-deleted) `src/integrations/bootstrap.ts`.
* SCM integrations remain on the legacy `IntegrationModule` registration
* pattern — the manifest pattern is PM-only (spec 006 scope).
*/

import { integrationRegistry } from '../integrations/registry.js';
import { GitHubSCMIntegration } from './scm-integration.js';

if (!integrationRegistry.getOrNull('github')) {
integrationRegistry.register(new GitHubSCMIntegration());
}
Loading
Loading