feat: operate lifecycle automation from admin consoles - #1563
Conversation
|
Warning Review limit reached
Next review available in: 15 minutes Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available. How can I continue?After more reviews become available, a review can be triggered using the To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews. How do review limits work?CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability. For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window. Please refer docs for additional details. Review details⚙️ Run configurationConfiguration used: Organization UI Review profile: ASSERTIVE Plan: Pro Plus Run ID: ⛔ Files ignored due to path filters (2)
📒 Files selected for processing (54)
📝 WalkthroughWalkthroughLifecycle automation을 위한 Admin React 상태 모델, source, 규칙·run·dry-run 콘솔, 생성형 admin console 데모, 테스트, API 문서, Problem 레지스트리와 공개 export가 추가되었습니다. ChangesLifecycle automation console
Estimated code review effort: 4 (Complex) | ~60 minutes Sequence Diagram(s)sequenceDiagram
participant Operator
participant LifecycleAutomationConsole
participant LifecycleAutomationSource
participant Registry
participant RunStore
participant Evaluator
Operator->>LifecycleAutomationConsole: inspect rules and select operation
LifecycleAutomationConsole->>LifecycleAutomationSource: load console state
LifecycleAutomationSource->>Registry: inspect or execute rule action
LifecycleAutomationSource->>RunStore: list filtered runs
LifecycleAutomationSource->>Evaluator: evaluate dry-run fixture
LifecycleAutomationSource-->>LifecycleAutomationConsole: rules, evidence, runs, and Problems
LifecycleAutomationConsole-->>Operator: render diagnostics and audited controls
Possibly related issues
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ 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 |
📊 Benchmark Results✅ All benchmarks passed
Updated: 2026-07-26T12:27:26.282Z · Commit: 06b113b |
There was a problem hiding this comment.
Actionable comments posted: 12
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
packages/create-croco-app/templates/admin-console/README.md.hbs (1)
31-36: 📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick winRecovery States 섹션에 lifecycle 복구 상태가 누락되었습니다.
Primary Workflow(25줄)와 Structure(58줄)에는 lifecycle automation이 추가되었지만, Recovery States는 여전히 API unavailable / Missing user / Contract drift / DI graph drift만 다룹니다. 이 PR이 다루는 stale descriptor(
admin-react/lifecycle-action-intent-stale), permission-denied, cooldown suppression, dry-run 실패, retryable failure 상태가 생성 앱 문서에 설명되지 않아 사용자가 콘솔에서 본 Problem code의 복구 경로를 찾을 수 없습니다.📝 제안 추가
- DI graph drift: 의도적으로 갱신할 때 `pnpm di:graph`를 실행합니다. `pnpm di:verify`는 기존 `.croco/build/di-graph.manifest.json`과 Project Map 산출물을 변경하지 않은 채 검사하고 `croco doctor --json`을 실행합니다. +- Lifecycle stale descriptor: descriptor fingerprint나 revision이 바뀌면 `admin-react/lifecycle-action-intent-stale`이 반환됩니다. 콘솔을 새로고침해 현재 version을 검토한 뒤 다시 실행합니다. +- Lifecycle permission denied: `lifecycle:read` / `lifecycle:write` / `lifecycle:dry-run` 권한이 없으면 각 Problem code와 함께 필요한 권한이 표시되며 액션 컨트롤은 노출되지 않습니다. +- Lifecycle cooldown suppression: cooldown 구간의 signal은 `suppressed-cooldown` outcome으로 run history에 남고 action은 dispatch되지 않습니다. +- Lifecycle retryable failure: recovery 계약이 replay/retry를 허용하는 run에만 재시도 컨트롤이 표시되고, admin-ops recovery evidence로 연결됩니다.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@packages/create-croco-app/templates/admin-console/README.md.hbs` around lines 31 - 36, Update the Recovery States section in the README template to document lifecycle automation recovery paths alongside the existing states. Cover stale descriptor (`admin-react/lifecycle-action-intent-stale`), permission-denied, cooldown suppression, dry-run failure, and retryable failure, including the corresponding user-visible Problem codes and recovery actions.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@packages/admin-react/README.md`:
- Around line 55-59: Update the dry-run documentation in the README to replace
the non-exported LifecycleDryRunResult type with the exported
LifecycleDryRunEvidence type, including references describing the evidence
returned by the dry-run method. Keep LifecycleDryRunResponse for the enclosing
response type where applicable.
In `@packages/admin-react/src/libs/lifecycleAutomation.ts`:
- Around line 420-436: Combine findRecovery and findRecoveryItem so the
items.find lookup for run.id occurs only once per run. Reuse the resulting
recoveryItem in buildRunOperation to derive the allowed retry/replay recovery
action, preserving the existing undefined behavior when no matching item or
action exists.
- Around line 519-526: Update listRuns to pass filters.limit through the
options.runStore.list call alongside tenantId and ruleId, then remove the
redundant in-memory slice while preserving matchesRunFilters processing and the
readonly LifecycleRun[] return behavior.
- Around line 646-667: Separate the parsePastedContext call in the dry-run flow
from the evaluator.dryRun catch-all so parsing failures return an invalid
response with a dedicated problem code. Register that new problem code in the
problem-code registry, while preserving safeFailure("dry-run") for evaluator or
other dry-run failures.
In `@packages/admin-react/src/libs/LifecycleAutomationConsole.ts`:
- Around line 223-231: Update the Cooldown column rendering in the operation run
display so the operation.run.status === "skipped" fallback uses a clear,
user-facing label describing that it was skipped for a reason other than
cooldown, replacing "not the suppression reason". Preserve the existing
"suppressed" label for cooldown_active and "passed" label for other outcomes.
In `@packages/admin-react/vitest.config.ts`:
- Around line 8-12: Update the resolve.alias configuration in vitest.config.ts
to add `@croco/lifecycle-core` mapped to the package’s source entry point,
alongside the existing `@croco/problems-core` alias. Ensure
LifecycleAutomationConsole.spec.ts resolves runtime imports from source without
relying on workspace dist builds.
In `@packages/create-croco-app/src/tests/templates-build.spec.ts`:
- Around line 406-410: Strengthen the LifecycleAutomationDemo.tsx assertion in
the templates build test by replacing the generic /DryRunFixture/ check with a
demo-specific fixture identifier such as “at-risk-tenant” or “paused-signal”.
Keep the validation focused on confirming that the dry-run fixture is actually
defined and consumed.
In
`@packages/create-croco-app/templates/admin-console/apps/console-web/src/App.tsx.hbs`:
- Around line 319-320: Update LifecycleAutomationDemo and its usage in App so it
receives the selected tenantId and uses that prop instead of the hardcoded
tenant_acme value for lifecycle data and display. Pass selectedTenantId from the
top-level tenant selector, preserving the existing TenantWorkspaceDemo scoping
behavior.
In
`@packages/create-croco-app/templates/admin-console/apps/console-web/src/LifecycleAutomationDemo.tsx`:
- Around line 541-546: Update audit evidence entries in the setAuditEvidence
flow to include a stable unique identifier alongside the display text, avoiding
duplicate React keys for repeated failure results without relying on array
indexes. Apply the same entry shape to the auditEvidence initial value created
by createDemoRuntime, and update consumers to use the identifier as the React
key while preserving the existing success and failure text.
- Line 315: Update the source construction around Object.assign so its inferred
return type is used directly. Remove the narrow LifecycleAutomationSource
declaration and the subsequent as GeneratedLifecycleSource cast, while
preserving the attached methods and resulting behavior.
- Around line 514-527: Handle rejected promises from createDemoRuntime/loadState
in the useEffect and from the runAction/runDryRun void calls by capturing
failures in the component’s failure state instead of leaving loading unresolved.
Surface failure in the render tree with role="alert", while preserving
successful state updates and cleanup behavior.
- Around line 155-186: Align the demo recovery item’s retryability with its
replay action in the items construction: if the demo intends to show replay as
permitted, change the failed item’s retryable state to true; otherwise set the
replay action’s allowed state to false. Ensure LifecycleAutomationDemo
consistently demonstrates that retry controls appear only when recovery is
allowed.
---
Outside diff comments:
In `@packages/create-croco-app/templates/admin-console/README.md.hbs`:
- Around line 31-36: Update the Recovery States section in the README template
to document lifecycle automation recovery paths alongside the existing states.
Cover stale descriptor (`admin-react/lifecycle-action-intent-stale`),
permission-denied, cooldown suppression, dry-run failure, and retryable failure,
including the corresponding user-visible Problem codes and recovery actions.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: ASSERTIVE
Plan: Pro Plus
Run ID: 4f5ff386-8739-4f7c-8625-116b88a9269f
⛔ Files ignored due to path filters (2)
packages/problems-core/src/generated/problem-code-registry.tsis excluded by!**/generated/**pnpm-lock.yamlis excluded by!**/pnpm-lock.yaml
📒 Files selected for processing (53)
.changeset/lifecycle-automation-console.mddocs/problem-code-registry.jsonpackages/admin-react/README.mdpackages/admin-react/package.jsonpackages/admin-react/src/index.tspackages/admin-react/src/libs/LifecycleAutomationConsole.tspackages/admin-react/src/libs/lifecycleAutomation.tspackages/admin-react/src/tests/LifecycleAutomationConsole.spec.tspackages/admin-react/tsconfig.jsonpackages/admin-react/vitest.config.tspackages/create-croco-app/src/helpers/croco-ranges.tspackages/create-croco-app/src/tests/e2e-generation.spec.tspackages/create-croco-app/src/tests/templates-build.spec.tspackages/create-croco-app/templates/admin-console/README.md.hbspackages/create-croco-app/templates/admin-console/apps/console-web/package.json.hbspackages/create-croco-app/templates/admin-console/apps/console-web/src/App.tsx.hbspackages/create-croco-app/templates/admin-console/apps/console-web/src/LifecycleAutomationDemo.tsxpackages/docs/src/content/docs/api/admin-react/src/functions/LifecycleAutomationConsole.mdpackages/docs/src/content/docs/api/admin-react/src/functions/LifecycleDryRunPanel.mdpackages/docs/src/content/docs/api/admin-react/src/functions/LifecycleRuleOperations.mdpackages/docs/src/content/docs/api/admin-react/src/functions/LifecycleRunHistory.mdpackages/docs/src/content/docs/api/admin-react/src/functions/classifyLifecycleRun.mdpackages/docs/src/content/docs/api/admin-react/src/functions/createLifecycleAutomationLoadingState.mdpackages/docs/src/content/docs/api/admin-react/src/functions/createLifecycleAutomationSource.mdpackages/docs/src/content/docs/api/admin-react/src/functions/diffLifecycleRuleDescriptors.mdpackages/docs/src/content/docs/api/admin-react/src/functions/loadLifecycleAutomationConsole.mdpackages/docs/src/content/docs/api/admin-react/src/interfaces/LifecycleAutomationSource.mdpackages/docs/src/content/docs/api/admin-react/src/type-aliases/LifecycleAutomationConsoleProps.mdpackages/docs/src/content/docs/api/admin-react/src/type-aliases/LifecycleAutomationConsoleState.mdpackages/docs/src/content/docs/api/admin-react/src/type-aliases/LifecycleAutomationEmptyState.mdpackages/docs/src/content/docs/api/admin-react/src/type-aliases/LifecycleAutomationLoadingState.mdpackages/docs/src/content/docs/api/admin-react/src/type-aliases/LifecycleAutomationPermissionDeniedState.mdpackages/docs/src/content/docs/api/admin-react/src/type-aliases/LifecycleAutomationReadyState.mdpackages/docs/src/content/docs/api/admin-react/src/type-aliases/LifecycleAutomationSourceOptions.mdpackages/docs/src/content/docs/api/admin-react/src/type-aliases/LifecycleDescriptorDiff.mdpackages/docs/src/content/docs/api/admin-react/src/type-aliases/LifecycleDryRunEvidence.mdpackages/docs/src/content/docs/api/admin-react/src/type-aliases/LifecycleDryRunFixture.mdpackages/docs/src/content/docs/api/admin-react/src/type-aliases/LifecycleDryRunFixtureDescriptor.mdpackages/docs/src/content/docs/api/admin-react/src/type-aliases/LifecycleDryRunRequest.mdpackages/docs/src/content/docs/api/admin-react/src/type-aliases/LifecycleDryRunResponse.mdpackages/docs/src/content/docs/api/admin-react/src/type-aliases/LifecycleOperationsProblem.mdpackages/docs/src/content/docs/api/admin-react/src/type-aliases/LifecycleRuleActionInput.mdpackages/docs/src/content/docs/api/admin-react/src/type-aliases/LifecycleRuleActionResult.mdpackages/docs/src/content/docs/api/admin-react/src/type-aliases/LifecycleRuleAdminAction.mdpackages/docs/src/content/docs/api/admin-react/src/type-aliases/LifecycleRuleOperation.mdpackages/docs/src/content/docs/api/admin-react/src/type-aliases/LifecycleRunActionEvidence.mdpackages/docs/src/content/docs/api/admin-react/src/type-aliases/LifecycleRunEvidence.mdpackages/docs/src/content/docs/api/admin-react/src/type-aliases/LifecycleRunFilters.mdpackages/docs/src/content/docs/api/admin-react/src/type-aliases/LifecycleRunOperation.mdpackages/docs/src/content/docs/api/admin-react/src/type-aliases/LifecycleRunOutcome.mdpackages/docs/src/content/docs/api/admin-react/src/type-aliases/LoadLifecycleAutomationOptions.mdpackages/docs/src/content/docs/en/reference/problem-recovery-cookbook.mdpublic-api-surface.snapshot.json
8f1c7c6 to
a875c41
Compare
There was a problem hiding this comment.
Actionable comments posted: 5
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@packages/admin-react/src/libs/LifecycleAutomationConsole.ts`:
- Around line 350-396: Extend the empty-state model used by
LifecycleAutomationConsole to carry dryRun results, then render the same
LifecycleDryRunPanel or alert output for empty states as for ready states.
Update the dry-run result conditional around state.kind === "ready" so
empty-state executions remain visible, while preserving existing fixture and
run-history behavior.
- Around line 180-193: Update the first cell rendered in the runs.map row within
LifecycleAutomationConsole to use a th element with scope="row" instead of td,
while preserving the existing Run ID link and fallback content.
In `@packages/admin-react/src/tests/LifecycleAutomationConsole.spec.ts`:
- Around line 423-470: Extend the lifecycle automation console tests around the
existing recovery-action fixture to cover an item with allowed: false or no
recoveryActions. Assert that the recovery/replay control is not rendered and
that the “Not declared safe” fallback text appears, while preserving the
existing allowed: true assertions.
- Around line 367-393: Extend the test “distinguishes invalid pasted context
from evaluator availability failures” to also stub the evaluator used by dryRun
to throw, then invoke dryRun with valid pasted context and assert the separate
evaluator-failure result: kind "problem" with the safeFailure("dry-run") output.
Keep the existing invalid pasted-context assertions and privacy checks
unchanged.
In `@packages/create-croco-app/templates/admin-console/README.md.hbs`:
- Line 40: Update the lifecycle dry-run failure documentation in the README
template to remove the unsupported pasted-context error, or explicitly identify
it as a framework-level contract rather than a generated-demo scenario. Keep the
documented fixture-not-found behavior and the statement that dry runs do not
consume production actions or cooldowns.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: ASSERTIVE
Plan: Pro Plus
Run ID: 088e8797-02fe-4f95-9f49-9e7183bdf43e
⛔ Files ignored due to path filters (2)
packages/problems-core/src/generated/problem-code-registry.tsis excluded by!**/generated/**pnpm-lock.yamlis excluded by!**/pnpm-lock.yaml
📒 Files selected for processing (53)
.changeset/lifecycle-automation-console.mddocs/problem-code-registry.jsonpackages/admin-react/README.mdpackages/admin-react/package.jsonpackages/admin-react/src/index.tspackages/admin-react/src/libs/LifecycleAutomationConsole.tspackages/admin-react/src/libs/lifecycleAutomation.tspackages/admin-react/src/tests/LifecycleAutomationConsole.spec.tspackages/admin-react/tsconfig.jsonpackages/admin-react/vitest.config.tspackages/create-croco-app/src/helpers/croco-ranges.tspackages/create-croco-app/src/tests/e2e-generation.spec.tspackages/create-croco-app/src/tests/templates-build.spec.tspackages/create-croco-app/templates/admin-console/README.md.hbspackages/create-croco-app/templates/admin-console/apps/console-web/package.json.hbspackages/create-croco-app/templates/admin-console/apps/console-web/src/App.tsx.hbspackages/create-croco-app/templates/admin-console/apps/console-web/src/LifecycleAutomationDemo.tsxpackages/docs/src/content/docs/api/admin-react/src/functions/LifecycleAutomationConsole.mdpackages/docs/src/content/docs/api/admin-react/src/functions/LifecycleDryRunPanel.mdpackages/docs/src/content/docs/api/admin-react/src/functions/LifecycleRuleOperations.mdpackages/docs/src/content/docs/api/admin-react/src/functions/LifecycleRunHistory.mdpackages/docs/src/content/docs/api/admin-react/src/functions/classifyLifecycleRun.mdpackages/docs/src/content/docs/api/admin-react/src/functions/createLifecycleAutomationLoadingState.mdpackages/docs/src/content/docs/api/admin-react/src/functions/createLifecycleAutomationSource.mdpackages/docs/src/content/docs/api/admin-react/src/functions/diffLifecycleRuleDescriptors.mdpackages/docs/src/content/docs/api/admin-react/src/functions/loadLifecycleAutomationConsole.mdpackages/docs/src/content/docs/api/admin-react/src/interfaces/LifecycleAutomationSource.mdpackages/docs/src/content/docs/api/admin-react/src/type-aliases/LifecycleAutomationConsoleProps.mdpackages/docs/src/content/docs/api/admin-react/src/type-aliases/LifecycleAutomationConsoleState.mdpackages/docs/src/content/docs/api/admin-react/src/type-aliases/LifecycleAutomationEmptyState.mdpackages/docs/src/content/docs/api/admin-react/src/type-aliases/LifecycleAutomationLoadingState.mdpackages/docs/src/content/docs/api/admin-react/src/type-aliases/LifecycleAutomationPermissionDeniedState.mdpackages/docs/src/content/docs/api/admin-react/src/type-aliases/LifecycleAutomationReadyState.mdpackages/docs/src/content/docs/api/admin-react/src/type-aliases/LifecycleAutomationSourceOptions.mdpackages/docs/src/content/docs/api/admin-react/src/type-aliases/LifecycleDescriptorDiff.mdpackages/docs/src/content/docs/api/admin-react/src/type-aliases/LifecycleDryRunEvidence.mdpackages/docs/src/content/docs/api/admin-react/src/type-aliases/LifecycleDryRunFixture.mdpackages/docs/src/content/docs/api/admin-react/src/type-aliases/LifecycleDryRunFixtureDescriptor.mdpackages/docs/src/content/docs/api/admin-react/src/type-aliases/LifecycleDryRunRequest.mdpackages/docs/src/content/docs/api/admin-react/src/type-aliases/LifecycleDryRunResponse.mdpackages/docs/src/content/docs/api/admin-react/src/type-aliases/LifecycleOperationsProblem.mdpackages/docs/src/content/docs/api/admin-react/src/type-aliases/LifecycleRuleActionInput.mdpackages/docs/src/content/docs/api/admin-react/src/type-aliases/LifecycleRuleActionResult.mdpackages/docs/src/content/docs/api/admin-react/src/type-aliases/LifecycleRuleAdminAction.mdpackages/docs/src/content/docs/api/admin-react/src/type-aliases/LifecycleRuleOperation.mdpackages/docs/src/content/docs/api/admin-react/src/type-aliases/LifecycleRunActionEvidence.mdpackages/docs/src/content/docs/api/admin-react/src/type-aliases/LifecycleRunEvidence.mdpackages/docs/src/content/docs/api/admin-react/src/type-aliases/LifecycleRunFilters.mdpackages/docs/src/content/docs/api/admin-react/src/type-aliases/LifecycleRunOperation.mdpackages/docs/src/content/docs/api/admin-react/src/type-aliases/LifecycleRunOutcome.mdpackages/docs/src/content/docs/api/admin-react/src/type-aliases/LoadLifecycleAutomationOptions.mdpackages/docs/src/content/docs/en/reference/problem-recovery-cookbook.mdpublic-api-surface.snapshot.json
47f561a to
0798a54
Compare
Outcome
@croco/admin-reactnow exposes React-independent lifecycle operation contracts and accessible console primitives for exact rule/version inspection, semantic descriptor comparison, audited activation and pause/resume/supersede transitions, redacted dry runs, run diagnosis, and safe recovery links.Rule operations require permission, actor, reason, idempotency, optimistic revision, and descriptor fingerprint evidence. Stale descriptors fail explicitly, idempotent replay remains valid, partial providers preserve stable Problems, browser-visible evidence excludes raw errors and idempotency keys, and retry controls appear only for recovery contracts declared safe.
The generated SaaS admin console now demonstrates activate, redacted dry-run, production match, cooldown suppression, pause, paused evaluation, and resume through a browser-safe in-memory adapter without browser-authored lifecycle code.
Fixes #1547
Verification
pnpm check— repository profile passed; 22/23 gates passed and one was not applicablepnpm build— 114/114 tasks passedpnpm --filter @croco/admin-react test— 50/50 tests passedpnpm docs:api:check— 112/112 tasks; 3,847 pages; generated docs matchedReview gates
Residual risk
The generated admin console intentionally uses an in-memory demonstration adapter. Production applications must provide their own authorized source adapter and durable lifecycle/admin-ops backends; the browser surface never accepts authored predicates or executable action code.
Summary by CodeRabbit