refactor: extract CooldownFollowUpRunner from CooldownSession (Wave 2A, #375)#398
refactor: extract CooldownFollowUpRunner from CooldownSession (Wave 2A, #375)#398
Conversation
#375) Extract follow-up analysis pipeline (prediction matching, calibration detection, hierarchical promotion, expiry check, friction analysis) into dedicated CooldownFollowUpRunner class with constructor DI. - CooldownFollowUpRunner (124L new) with CooldownFollowUpDeps interface - CooldownSession 1,201 -> 1,098 lines (-103L, delegating via followUpRunner) - 15 BDD scenarios (CPO + CQO audited, pipeline ordering verified) - 20 unit tests covering all analyses, error isolation, ordering - CRAP < 8, ArchUnit 14 of 15, mutation 88.89% on covered code Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
|
Warning Rate limit exceeded
⌛ How to resolve this issue?After the wait time has elapsed, a review can be triggered using the We recommend that you space out your commits to avoid hitting the rate limit. 🚦 How do rate limits work?CodeRabbit enforces hourly rate limits for each developer per organization. Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout. Please see our FAQ for further information. ℹ️ Review info⚙️ Run configurationConfiguration used: Organization UI Review profile: ASSERTIVE Plan: Pro Run ID: 📒 Files selected for processing (2)
📝 WalkthroughWalkthroughThis PR extracts cooldown follow-up orchestration logic from Changes
Estimated code review effort🎯 4 (Complex) | ⏱️ ~50 minutes Possibly related PRs
Poem
🚥 Pre-merge checks | ✅ 2 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 2
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@src/features/cycle-management/cooldown-follow-up-runner.steps.ts`:
- Around line 83-90: The logger spies created in the Background (loggerWarnSpy
and loggerDebugSpy on logger) persist across scenarios and leak call history;
add an After hook for the CooldownFollowUpRunnerWorld that calls
vi.restoreAllMocks() (or vi.clearAllMocks() as preferred) to restore/reset the
spies after each scenario, mirroring the pattern used by the SessionBridgeWorld
After hook; also apply the same After cleanup wherever other logger spies are
created (the other block creating spies) so each scenario runs with fresh mocks.
In `@src/features/cycle-management/cooldown-follow-up-runner.test.ts`:
- Line 1: Remove the explicit imports of Vitest globals from the import
statement: eliminate describe, it, expect (and any other test globals like
beforeEach/afterEach if they are only used as globals) and only import vi if you
need the mocking API; rely on the repo's globals: true setting so
describe/it/expect/beforeEach/afterEach are available without import. Update the
import line that currently reads "import { vi, describe, it, expect, beforeEach,
afterEach } from 'vitest';" to only include vi when used, or remove the import
entirely if vi is unused.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: ASSERTIVE
Plan: Pro
Run ID: e76040ec-92ae-4a23-8a75-50b5debc5263
📒 Files selected for processing (7)
src/acceptance/setup.tssrc/features/cycle-management/cooldown-follow-up-runner.featuresrc/features/cycle-management/cooldown-follow-up-runner.steps.tssrc/features/cycle-management/cooldown-follow-up-runner.test.tssrc/features/cycle-management/cooldown-follow-up-runner.tssrc/features/cycle-management/cooldown-session.tsstryker.config.mjs
📜 Review details
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
- GitHub Check: Lint, Tests, Quality Loop & Build
🧰 Additional context used
📓 Path-based instructions (5)
src/acceptance/**/*.ts
📄 CodeRabbit inference engine (AGENTS.md)
Register step files for
.featurefiles throughsrc/acceptance/setup.ts
Files:
src/acceptance/setup.ts
src/**/*.{ts,js}
📄 CodeRabbit inference engine (CLAUDE.md)
Use ESM-only imports with
.jsextensions on all internal imports. Project must have"type": "module"in package.json.
Files:
src/acceptance/setup.tssrc/features/cycle-management/cooldown-session.tssrc/features/cycle-management/cooldown-follow-up-runner.test.tssrc/features/cycle-management/cooldown-follow-up-runner.steps.tssrc/features/cycle-management/cooldown-follow-up-runner.ts
src/**/*.ts
📄 CodeRabbit inference engine (CLAUDE.md)
src/**/*.ts: Use path aliases for imports:@domain/*→src/domain/*,@infra/*→src/infrastructure/*,@features/*→src/features/*,@shared/*→src/shared/*,@cli/*→src/cli/*. Aliases must be defined in tsconfig.json and vitest.config.ts.
Dependency direction must be strictly enforced: domain → infrastructure → features → shared → cli. No reverse imports allowed.
Coverage thresholds must maintain 80% statements/functions/lines and 75% branches. Coverage excludes test files andsrc/cli/index.ts.
Files:
src/acceptance/setup.tssrc/features/cycle-management/cooldown-session.tssrc/features/cycle-management/cooldown-follow-up-runner.test.tssrc/features/cycle-management/cooldown-follow-up-runner.steps.tssrc/features/cycle-management/cooldown-follow-up-runner.ts
src/**/*.test.ts
📄 CodeRabbit inference engine (CLAUDE.md)
Test files must be colocated next to source files as
*.test.tswith Vitest globals enabled (no need to import describe/it/expect).
Files:
src/features/cycle-management/cooldown-follow-up-runner.test.ts
**/*.feature
📄 CodeRabbit inference engine (AGENTS.md)
**/*.feature: Co-locate.featurefiles with the feature they specify
For new behavior or behavior clarification, acceptance scenarios must exist and fail before implementation
Files:
src/features/cycle-management/cooldown-follow-up-runner.feature
🧠 Learnings (10)
📚 Learning: 2026-03-15T01:51:21.342Z
Learnt from: CR
Repo: cmbays/kata PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-03-15T01:51:21.342Z
Learning: Applies to src/acceptance/**/*.ts : Register step files for `.feature` files through `src/acceptance/setup.ts`
Applied to files:
src/acceptance/setup.tsstryker.config.mjssrc/features/cycle-management/cooldown-follow-up-runner.steps.ts
📚 Learning: 2026-03-15T01:51:21.342Z
Learnt from: CR
Repo: cmbays/kata PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-03-15T01:51:21.342Z
Learning: Run focused mutation testing on changed behavior-heavy modules
Applied to files:
stryker.config.mjs
📚 Learning: 2026-03-15T01:51:21.342Z
Learnt from: CR
Repo: cmbays/kata PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-03-15T01:51:21.342Z
Learning: Focused mutation testing must be run for changed business logic or orchestration seams with meaningful survivors explicitly called out
Applied to files:
stryker.config.mjssrc/features/cycle-management/cooldown-follow-up-runner.test.ts
📚 Learning: 2026-03-15T01:51:21.342Z
Learnt from: CR
Repo: cmbays/kata PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-03-15T01:51:21.342Z
Learning: Applies to src/**/{cli,orchestrat}*.ts : Prefer extracting pure helpers from CLI/orchestration files before adding more direct tests to large side-effect-heavy modules
Applied to files:
stryker.config.mjssrc/features/cycle-management/cooldown-follow-up-runner.test.ts
📚 Learning: 2026-03-21T22:25:46.055Z
Learnt from: CR
Repo: cmbays/kata PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-21T22:25:46.055Z
Learning: Applies to src/**/*.ts : Dependency direction must be strictly enforced: domain → infrastructure → features → shared → cli. No reverse imports allowed.
Applied to files:
stryker.config.mjs
📚 Learning: 2026-03-21T22:25:46.055Z
Learnt from: CR
Repo: cmbays/kata PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-21T22:25:46.055Z
Learning: Applies to src/{cli,domain/types}/index.ts : Two entrypoints must be defined via tsup: `cli/index` (bin) and `domain/types/index` (library exports).
Applied to files:
stryker.config.mjs
📚 Learning: 2026-03-21T22:25:46.055Z
Learnt from: CR
Repo: cmbays/kata PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-21T22:25:46.055Z
Learning: Applies to src/**/*.ts : Coverage thresholds must maintain 80% statements/functions/lines and 75% branches. Coverage excludes test files and `src/cli/index.ts`.
Applied to files:
stryker.config.mjs
📚 Learning: 2026-03-15T01:51:21.342Z
Learnt from: CR
Repo: cmbays/kata PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-03-15T01:51:21.342Z
Learning: Applies to src/**/*.command.test.ts : Keep command-level tests focused on wiring and delegation; put parsing/formatting/selection behavior into direct unit tests
Applied to files:
stryker.config.mjssrc/features/cycle-management/cooldown-follow-up-runner.test.ts
📚 Learning: 2026-03-21T22:25:46.055Z
Learnt from: CR
Repo: cmbays/kata PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-21T22:25:46.055Z
Learning: Applies to src/**/*.ts : Use path aliases for imports: `domain/*` → `src/domain/*`, `infra/*` → `src/infrastructure/*`, `features/*` → `src/features/*`, `shared/*` → `src/shared/*`, `cli/*` → `src/cli/*`. Aliases must be defined in tsconfig.json and vitest.config.ts.
Applied to files:
stryker.config.mjs
📚 Learning: 2026-03-21T22:25:46.055Z
Learnt from: CR
Repo: cmbays/kata PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-21T22:25:46.055Z
Learning: Applies to src/**/*.test.ts : Test files must be colocated next to source files as `*.test.ts` with Vitest globals enabled (no need to import describe/it/expect).
Applied to files:
stryker.config.mjssrc/features/cycle-management/cooldown-follow-up-runner.test.ts
🔇 Additional comments (6)
src/features/cycle-management/cooldown-follow-up-runner.ts (2)
42-123: Nice preservation of ordering and failure isolation.The extracted runner keeps the pipeline order explicit and contains non-critical failures to warnings without aborting cooldown.
8-8: 🧹 Nitpick | 🔵 TrivialFinish isolating this seam from
CooldownSessionhelpers.
CooldownFollowUpRunnerstill reaches back intocooldown-session.helpers.ts, so part of the extracted follow-up behavior remains coupled to the old orchestration module. A small runner-local/shared helper for expiry-message formatting would keep the extraction cleaner; if the formatter stays shared, use the@features/...alias instead of./....Based on learnings, "Applies to src/**/{cli,orchestrat}*.ts : Prefer extracting pure helpers from CLI/orchestration files before adding more direct tests to large side-effect-heavy modules."
⛔ Skipped due to learnings
Learnt from: CR Repo: cmbays/kata PR: 0 File: AGENTS.md:0-0 Timestamp: 2026-03-15T01:51:21.342Z Learning: Applies to src/**/{cli,orchestrat}*.ts : Prefer extracting pure helpers from CLI/orchestration files before adding more direct tests to large side-effect-heavy modulesLearnt from: CR Repo: cmbays/kata PR: 0 File: AGENTS.md:0-0 Timestamp: 2026-03-15T01:51:21.342Z Learning: Applies to src/**/*.command.test.ts : Keep command-level tests focused on wiring and delegation; put parsing/formatting/selection behavior into direct unit testsstryker.config.mjs (1)
19-19: Good mutation-scope update.Adding the new runner here keeps the extracted orchestration seam inside focused mutation coverage.
Based on learnings, "Focused mutation testing must be run for changed business logic or orchestration seams with meaningful survivors explicitly called out."
src/acceptance/setup.ts (1)
5-5: Good step registration.This ensures the new cooldown follow-up feature is actually loaded by the acceptance harness.
As per coding guidelines, "Register step files for
.featurefiles throughsrc/acceptance/setup.ts."src/features/cycle-management/cooldown-session.ts (1)
268-293: Nice single delegation seam.Resolving the collaborators once and routing both
run()andprepare()throughfollowUpRunnershould keep future follow-up changes from drifting between the two paths.Also applies to: 549-549, 605-605
src/features/cycle-management/cooldown-follow-up-runner.feature (1)
1-116: Good acceptance surface for this refactor.These scenarios lock down ordering, optional capability behavior, and failure isolation—the exact contract this extraction changes.
As per coding guidelines, "For new behavior or behavior clarification, acceptance scenarios must exist and fail before implementation."
src/features/cycle-management/cooldown-follow-up-runner.test.ts
Outdated
Show resolved
Hide resolved
- Add After hook to steps file to reset logger spies between scenarios - Remove explicit Vitest globals imports (repo has globals: true) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Both findings addressed: After hook added for spy cleanup, Vitest globals imports removed.
Summary\n\n- Extract follow-up analysis pipeline into dedicated
CooldownFollowUpRunnerclass (#375 Wave 2A)\n- 5 analyses extracted: prediction matching, calibration detection, hierarchical promotion, expiry check, friction analysis\n- CooldownSession 1,201 → 1,098 lines (-103L), CooldownFollowUpRunner 124L new\n- Constructor DI withCooldownFollowUpDepsinterface usingPick<>for collaborators\n\n## Quality Loop Results\n\n| Gate | Result |\n|------|--------|\n| BDD | 15 scenarios (CPO + CQO audited) |\n| Unit tests | 20 tests |\n| Typecheck | 0 errors |\n| CRAP | PASS (worst 6.0, threshold 8) |\n| ArchUnit | 14 of 15 (pre-existing CycleManager LCOM4) |\n| Mutation | 88.89% on covered code |\n| Full suite | 3,453 unit + 80 acceptance tests pass |\n\n## Key Design Decisions\n\n- Pipeline ordering preserved: calibration runs after prediction matching (verified by BDD scenario usinginvocationCallOrder)\n- Per-run error isolation: each analysis catches errors per-run so one bad run doesn't poison the batch\n- Duck-typedcheckExpiry: knowledge store capability detection preserved as-is\n- Nullable deps pattern:predictionMatcher | nullfor optional analyses\n\nCloses part of #375\n\n## Test plan\n\n- [x] All 15 BDD scenarios pass\n- [x] All 20 unit tests pass\n- [x] Full unit suite (3,453 tests) passes\n- [x] Full acceptance suite (80 tests) passes\n- [x] Typecheck clean\n- [x] CRAP analysis passes\n- [x] Mutation testing above threshold\n\n🤖 Generated with Claude CodeSummary by CodeRabbit
New Features
Tests