Skip to content

feat(lifecycle): replace hardcoded agentType branching with profile-driven lifecycle hooks#1016

Merged
aaight merged 1 commit intodevfrom
feature/profile-driven-lifecycle-hooks
Mar 23, 2026
Merged

feat(lifecycle): replace hardcoded agentType branching with profile-driven lifecycle hooks#1016
aaight merged 1 commit intodevfrom
feature/profile-driven-lifecycle-hooks

Conversation

@aaight
Copy link
Copy Markdown
Collaborator

@aaight aaight commented Mar 23, 2026

Summary

  • Extend AgentDefinition schema with optional hooks.lifecycle block (moveOnPrepare, moveOnSuccess, linkPR, syncChecklist)
  • Expose lifecycleHooks from AgentProfile resolved from the definition
  • Replace agentType === 'implementation' checks in PMLifecycleManager with profile-driven hooks
  • Replace agentType === 'implementation' check in ProgressMonitor.tick() with syncChecklist config flag
  • Add lifecycle hooks to implementation.yaml; all other agents default to no-op

Trello Card

https://trello.com/c/69c198a5184519ee8c4d2fa4

Changes

Schema (src/agents/definitions/schema.ts)

Added LifecycleHooksSchema with optional fields moveOnPrepare, moveOnSuccess, linkPR, syncChecklist. Added lifecycle to IntegrationHooksSchema.

AgentProfile (src/agents/definitions/profiles.ts)

Added lifecycleHooks: LifecycleHooks field to AgentProfile interface. Resolved from def.hooks?.lifecycle ?? {} — empty object (no-op) when not defined.

PMLifecycleManager (src/pm/lifecycle.ts)

  • prepareForAgent(workItemId, hooks: LifecycleHooks) — uses hooks.moveOnPrepare status key to optionally move the work item
  • handleSuccess(workItemId, hooks: LifecycleHooks, prUrl?, progressCommentId?) — uses hooks.moveOnSuccess and hooks.linkPR instead of checking agentType

ProgressMonitor (src/backends/progressMonitor.ts, progressLifecycle.ts, adapter.ts)

Added optional syncChecklist field to ProgressMonitorConfig. The tick function uses this.config.syncChecklist instead of agentType === 'implementation'. buildProgressMonitorConfig accepts a syncChecklist parameter. adapter.ts passes profile.lifecycleHooks.syncChecklist to the config builder.

Execution Pipeline (src/triggers/shared/agent-execution.ts)

Loads lifecycle hooks from the agent profile via getAgentProfile(agentType) (best-effort, defaults to {} on failure). Passes hooks to prepareForAgent and handleSuccess.

implementation.yaml

Added lifecycle block:

hooks:
  lifecycle:
    moveOnPrepare: inProgress
    moveOnSuccess: inReview
    linkPR: true
    syncChecklist: true

Test plan

  • All 6677 unit tests pass (npm test)
  • Lint passes (npm run lint)
  • TypeScript type checks pass (npm run typecheck)
  • Updated lifecycle tests to verify profile-driven behavior (hooks objects instead of agentType strings)
  • Updated progressMonitor tests to verify syncChecklist flag behavior
  • Backward compat: agents without lifecycle block get empty hooks (no-op behavior)

🤖 Generated with Claude Code

🕵️ claude-code · claude-sonnet-4-6 · run details

Copy link
Copy Markdown
Collaborator

@nhopeatall nhopeatall left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Summary

LGTM — Clean, well-scoped refactoring that replaces hardcoded agentType === 'implementation' branching in PMLifecycleManager and ProgressMonitor with profile-driven lifecycle hooks. The design is sound: hooks are defined in YAML, resolved through AgentProfile, and consumed at the right layers. Backward compatibility is preserved via defaults ({} for hooks, false for syncChecklist).

Minor Observations

Should Consider (non-blocking)

  • src/pm/lifecycle.ts:77-78, 91-93 — The hooks.moveOnPrepare as keyof typeof this.pmConfig.statuses cast silently resolves to undefined if someone puts an invalid status key (e.g., moveOnPrepare: typo) in their YAML definition. This is safe (because safeMove guards against undefined), but it could be confusing to debug. Consider either (a) validating the string against known status keys at resolution time, or (b) logging a warning when the lookup yields undefined despite the hook being set. Not blocking because definition authors are the only ones writing these values, and the schema could later constrain moveOnPrepare/moveOnSuccess to an enum.

The remaining agentType === 'implementation' references in ack-comments.ts and handleSuccessOnlyForAgentType: 'implementation' in integration.ts are correctly outside this PR's scope — they control GitHub-specific behavior (comment cleanup and execution gating), not PM lifecycle hooks.

🕵️ claude-code · claude-opus-4-6 · run details

@aaight aaight merged commit be92564 into dev Mar 23, 2026
8 checks passed
@codecov
Copy link
Copy Markdown

codecov Bot commented Mar 23, 2026

Codecov Report

❌ Patch coverage is 89.28571% with 6 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
src/triggers/shared/agent-execution.ts 60.00% 6 Missing ⚠️

📢 Thoughts on this report? Let us know!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants