Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
58 commits
Select commit Hold shift + click to select a range
5f9ef07
chore(deps): bump hono from 4.12.12 to 4.12.14
dependabot[bot] Apr 16, 2026
679c6da
docs(006): add spec + plans + coverage map for PM integration plug-an…
zbigniewsobiecki Apr 16, 2026
5f0144e
chore(006): lock plan 006/1 as .wip
zbigniewsobiecki Apr 16, 2026
7c3161e
feat(integrations): plan 006/1 — PM provider manifest + conformance h…
zbigniewsobiecki Apr 16, 2026
e7cc117
Merge pull request #1125 from mongrel-intelligence/feat/006-infrastru…
zbigniewsobiecki Apr 16, 2026
563ddba
docs(006/2): fix plan drift — Trello HMAC-SHA1 + useProviderHooks ext…
zbigniewsobiecki Apr 16, 2026
9eadb31
chore(006): lock plan 006/2 as .wip
zbigniewsobiecki Apr 16, 2026
394f0db
feat(006/2): trello manifest wiring (task 1)
zbigniewsobiecki Apr 16, 2026
46c5b35
feat(006/2): trello migrated onto PM provider manifest
zbigniewsobiecki Apr 16, 2026
4c12556
fix(006/2): inline trello config build — no buildTrelloIntegrationCon…
zbigniewsobiecki Apr 16, 2026
ece9143
Merge pull request #1126 from mongrel-intelligence/feat/006-migrate-t…
zbigniewsobiecki Apr 16, 2026
cced9ac
chore(006): lock plan 006/3 as .wip
zbigniewsobiecki Apr 16, 2026
7a3fd90
feat(006/3): jira migrated onto PM provider manifest
zbigniewsobiecki Apr 16, 2026
0ed056f
Merge pull request #1127 from mongrel-intelligence/feat/006-migrate-jira
zbigniewsobiecki Apr 16, 2026
863ffb8
chore(006): lock plan 006/4 as .wip
zbigniewsobiecki Apr 16, 2026
5697b1f
feat(006/4): linear migrated onto PM provider manifest
zbigniewsobiecki Apr 16, 2026
aae4d45
Merge pull request #1128 from mongrel-intelligence/feat/006-migrate-l…
zbigniewsobiecki Apr 16, 2026
e2808f1
chore(006): lock plan 006/5 as .wip
zbigniewsobiecki Apr 16, 2026
bec8d24
feat(006/5): delete legacy bootstrap; pmRegistry becomes a delegate
zbigniewsobiecki Apr 16, 2026
6eccda5
docs(006): spec complete — all plans done
zbigniewsobiecki Apr 16, 2026
491d965
Merge pull request #1129 from mongrel-intelligence/feat/006-cleanup-l…
zbigniewsobiecki Apr 16, 2026
ce101a3
docs(002): mark spec as .done — all plans already landed
zbigniewsobiecki Apr 16, 2026
2c60244
Merge pull request #1120 from mongrel-intelligence/dependabot/npm_and…
zbigniewsobiecki Apr 16, 2026
906f8fc
fix(prWorkItems): preserve workItemId across racing pipeline writers …
zbigniewsobiecki Apr 16, 2026
cfbeedf
fix(cli,backlog-mgr): register PM providers in CLI; load Linear pipel…
zbigniewsobiecki Apr 16, 2026
23dd458
fix(snapshots): actually rmi evicted images + reconcile orphans on st…
zbigniewsobiecki Apr 16, 2026
db6a5bb
fix(pm): unify listWorkItems contract so backlog-manager sees Linear …
zbigniewsobiecki Apr 16, 2026
cfad9b8
fix(cli): synthesize Linear PM scope so cascade-tools pm works for Li…
zbigniewsobiecki Apr 16, 2026
1225ea8
feat(007): robust review dispatch — per-type lock + post-completion h…
zbigniewsobiecki Apr 17, 2026
4109c23
fix(linear): create issues directly in backlog state via stateId (#1137)
zbigniewsobiecki Apr 17, 2026
93fddbf
fix(linear): preserve projectId through config mapper (#1138)
zbigniewsobiecki Apr 17, 2026
a4b9a25
fix(linear): pass stateId when creating checklist sub-issues (#1139)
zbigniewsobiecki Apr 17, 2026
c4561c3
feat(008): inline markdown checklists for Linear and JIRA (#1140)
zbigniewsobiecki Apr 18, 2026
d1a3ac1
feat(triggers): support PM triggers for work items created directly i…
Apr 18, 2026
2c2215d
fix(tests): clear JIRA env vars in credential-scoping beforeEach
Apr 18, 2026
37540c5
fix(config): add projectId to LinearConfigSchema so Zod stops strippi…
zbigniewsobiecki Apr 18, 2026
32987ac
docs(009): add spec + plans for PM integration hardening
zbigniewsobiecki Apr 18, 2026
3a27fdb
chore(009): lock plan 1 as .wip
zbigniewsobiecki Apr 18, 2026
f752651
feat(009/1): branded ID types + PMProvider/manifest extensions
zbigniewsobiecki Apr 18, 2026
3bcd6c8
feat(009/1): single integrations entrypoint + usage guard
zbigniewsobiecki Apr 18, 2026
623e812
feat(009/1): fake PM provider + expanded behavioral conformance harness
zbigniewsobiecki Apr 18, 2026
00dae2a
feat(009/1): auth-header provenance test + lefthook wiring
zbigniewsobiecki Apr 18, 2026
b5b7281
feat(009/1): generic pm.discover endpoint + wizard generator + docs
zbigniewsobiecki Apr 18, 2026
e6f2695
chore(009/1): mark plan 1 as .done
zbigniewsobiecki Apr 18, 2026
13bc507
chore(009/2): lock plan 2 as .wip
zbigniewsobiecki Apr 18, 2026
34a434f
feat(009/2): trello configSchema discovery branded ids
zbigniewsobiecki Apr 18, 2026
9896ed7
chore(009/2): trello migrated, plan done
zbigniewsobiecki Apr 18, 2026
4dc5ad6
chore(009/3): lock plan 3 as .wip
zbigniewsobiecki Apr 18, 2026
8bcbbfd
chore(009/3): jira migrated, plan done
zbigniewsobiecki Apr 18, 2026
d6a2edb
chore(009/4): lock plan 4 as .wip
zbigniewsobiecki Apr 18, 2026
5017f0c
chore(009/4): linear migrated, plan done
zbigniewsobiecki Apr 18, 2026
794cdca
chore(009/5): lock plan 5 with narrowed scope
zbigniewsobiecki Apr 18, 2026
09bf5c0
chore(009/5): cleanup done, spec 009 complete
zbigniewsobiecki Apr 18, 2026
1b5b2cf
chore(spec-009): all plans complete, spec done
zbigniewsobiecki Apr 18, 2026
754c6b5
Merge pull request #1143 from mongrel-intelligence/spec-009-pm-hardening
zbigniewsobiecki Apr 18, 2026
297a7e0
Merge pull request #1141 from mongrel-intelligence/feature/pm-trigger…
zbigniewsobiecki Apr 18, 2026
0e66346
feat(triggers): onCreate/onMove params for pm:status-changed
zbigniewsobiecki Apr 18, 2026
f145008
Merge pull request #1145 from mongrel-intelligence/feature/pm-status-…
zbigniewsobiecki Apr 18, 2026
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
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,8 @@ test-results/

# Claude Code — commit settings.json but exclude local settings (may contain secrets)
.claude/settings.local.json
# Claude Code — local scheduled-task state (per-machine, not for sharing)
.claude/scheduled_tasks.lock

# Progress comment state file (legacy — kept to ignore stale files from older runs)
.cascade-progress-comment-id
Expand Down
12 changes: 12 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,18 @@ All notable user-visible changes to CASCADE are documented here. The format is l

## Unreleased

### Changed

- **Linear and JIRA checklists are now inline markdown, not sub-issues / subtasks.** Acceptance criteria, implementation steps, and other checklist items added by CASCADE agents (via `AddChecklist` / `AddChecklistItem`) now live as `- [ ]` / `- [x]` markdown checkboxes inside the parent issue's description, under a `### {Checklist Name}` heading. Previously these created full sub-issues (Linear) or subtasks (JIRA) — one per item — which cluttered boards and inflated backlog counts (a single split could create 30+ orphan items). The PMProvider interface is unchanged; only the Linear and JIRA adapter internals changed. Trello continues to use its native checklist API. Forward-only — existing sub-issues / subtasks created before this change are not migrated. See [spec 008](docs/specs/008-inline-checklists.md.done) and the new "Checklist implementation by provider" section in [src/integrations/README.md](src/integrations/README.md).

### Internal

- **PM integration plug-and-play (infrastructure).** Introduced `PMProviderManifest` as the canonical per-provider contract — one object declares credentials, webhook route and verifier, router adapter, trigger handlers, platform client, job-id extractor, and optional label-creation hook. Landed `pmProviderRegistry`, a conformance test harness (`tests/unit/integrations/pm-conformance.test.ts`), shared helpers (`_shared/auth-headers.ts`, `_shared/webhook-verifier.ts`, `_shared/label-id-resolver.ts`, `_shared/project-id-extractor.ts`), a new `pm.discovery` tRPC router, and a frontend provider-wizard registry with a generic step renderer. Dormant in this release — Trello, JIRA, and Linear continue to register through the legacy path; they migrate onto the manifest in follow-up PRs. No operator-visible changes. Closes plan 006/1 of spec [006](docs/specs/006-pm-integration-plug-and-play.md).
- **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

- **Linear PM — optional Project scope.** Operators can now narrow a Linear-backed CASCADE project to a specific Linear Project (initiative) in the PM wizard's "Board / Project Selection" step. When set, CASCADE only responds to issues that belong to that Linear Project; webhooks for issues outside the scope are silently dropped by the router (with a structured `logger.info` entry), outbound listings are scoped to the project, and newly-created issues (including checklist sub-issues) inherit the project. Leave the new selector empty to preserve existing team-wide behavior. Because Linear's data model requires every issue to belong to a team and scopes workflow states per team, status mappings stay team-scoped. For cross-team Linear Projects, CASCADE responds to the **intersection** of the configured team and project only (sibling-team issues in the same project are ignored). No migration required — existing Linear integrations are unaffected. (Spec [005](docs/specs/005-linear-project-scope.md.done).)
Expand Down
6 changes: 5 additions & 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 integration, trigger, or agent**, see @src/integrations/README.md — don't improvise, it covers all extension points.
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 a **behavioral conformance harness** (spec 009 — config round-trip, discovery shape, full lifecycle scenario, auth-header provenance, single-entrypoint invariant). Each provider owns its Zod config schema (`src/integrations/pm/<provider>/config-schema.ts`) as the single source of truth — the central `src/config/schema.ts` imports it. PM adapter method signatures use branded `StateId` / `LabelId` / `ContainerId` from `src/pm/ids.ts` to make state-name-vs-ID confusion a compile error at direct-adapter call sites. All runtime surfaces (router, worker, CLI, dashboard) register integrations through a single entrypoint at `src/integrations/entrypoint.ts`. 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 Expand Up @@ -117,6 +117,10 @@ cascade projects trigger-set <project-id> --agent <type> --event <event> --enabl

Some triggers take params (e.g. `review` + `scm:check-suite-success` accepts `{"authorMode":"own"|"external"}`). Legacy configs on `project_integrations.triggers` are auto-migrated on merge to `dev`/`main`.

**Work-item concurrency lock** — the router prevents duplicate agent runs via a per-agent-type lock on `(projectId, workItemId, agentType)`. Only same-type duplicates are blocked; **different agent types can run concurrently** on the same work item (e.g. review starts while implementation's container is still cleaning up). The lock has a 30-minute TTL hard ceiling that auto-clears stale entries after router restart.

**Post-completion review dispatch** — when an implementation agent succeeds with a PR, the execution pipeline checks CI status and fires the review agent deterministically (before the container exits). This guarantees review dispatch within seconds of implementation completion, regardless of GitHub webhook timing. Uses the same `claimReviewDispatch` dedup key as the `check-suite-success` trigger, so the two paths cannot double-enqueue.

## Review agent — context shape (debugging)

Review agent receives a **compact per-file diff context**, not full file contents. Each changed file is a `### <file> (<status>, +N -M)` section with a unified diff hunk. Budget: `REVIEW_DIFF_CONTEXT_TOKEN_LIMIT` = 200k tokens, per-file cap 10%.
Expand Down
6 changes: 6 additions & 0 deletions bin/cascade-tools.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,12 @@ import { dirname, resolve } from 'node:path';
import { fileURLToPath } from 'node:url';
import { Config, run } from '@oclif/core';

// Bootstrap all integrations before oclif loads any command. The CLI
// runs commands lazily, and Spec 006/5 removed the legacy self-bootstrap
// path, so side-effect imports have to fire at the entry point.
// Without this, `cascade-tools pm <cmd>` throws `Unknown PM integration type`.
await import('../dist/cli/bootstrap.js');

// cascade-tools uses its own oclif config independent of package.json,
// which now points to the dashboard CLI (cascade binary).
const __dirname = dirname(fileURLToPath(import.meta.url));
Expand Down
Loading
Loading