Skip to content

SDK-owned terminal lifecycle policy and durable project history - #846

Merged
unbraind merged 2 commits into
mainfrom
feat/sdk-lifecycle-policy
Jul 31, 2026
Merged

unbraind merged 2 commits into
mainfrom
feat/sdk-lifecycle-policy

Conversation

@unbraind

@unbraind unbraind commented Jul 31, 2026 •

Copy link
Copy Markdown
Owner

What changed

  • moved the close transaction into the public SDK lifecycle layer and reduced the CLI close module to a compatibility shim
  • added public terminal reason and predecessor-edge policy primitives shared by CLI, SDK, and MCP routes
  • stopped update --status closed and direct terminal create from synthesizing immutable close reasons
  • preserved blocked_by dependency rows through close, reopen, and reclose while clearing only transient blocked-state scalars
  • added SDK migration documentation, a compilable SDK-only example, classified public-surface additions, regenerated error provenance, and generated changelog entries

Why

Terminal lifecycle policy lived privately in CLI command modules. That caused two concrete defects: one terminal route bypassed close-reason governance by inventing evidence, and closing a dependent deleted the ordering edges needed to understand historical project context. The SDK now owns this tranche of lifecycle semantics so every presentation surface uses one operation and consumers can inspect or select policy explicitly.

PM lineage

pm-xm0id4 and pm-2ew0w3 are complete. pm-z5pmf8 remains open and unclaimed because the create/update/delete/restore/context/planning SDK-to-CLI inversions are explicitly outside this delivered lifecycle tranche.

Verification

  • 6,610 tests; 100% statements, branches, functions, and lines
  • build, typecheck, ESLint, jscpd, CodeFactor/static-quality, 100% docstring coverage
  • SDK public-surface, package parity, entrypoint cost, CLI transport, token-budget, context/retrieval evaluation gates
  • isolated compiled CLI: predecessor survives close → reopen → reclose; reasonless update returns close_reason_required
  • fresh packed npm and Bun consumers import SDK lifecycle primitives and run contained npx/bunx binaries
  • pnpm audit --audit-level moderate: no known vulnerabilities
  • secrets scan, packed-npx smoke, and 88-command package-first dogfood
  • Sentry/telemetry: critical=0, high=0 over 14 days; best-effort telemetry gate passed

Hosted analysis and review gates are expected to complete against this immutable PR head.

Summary by Sourcery

Move terminal lifecycle semantics into an SDK-owned close operation while aligning reason governance and predecessor-edge policy across CLI, SDK, and MCP surfaces.

Bug Fixes:

  • Enforce consistent close_reason_required behavior across direct close, update --status closed, and direct terminal create so terminal transitions never synthesize immutable reasons.
  • Preserve blocked_by predecessor dependency edges across close, reopen, and reclose cycles while still clearing transient blocked state scalars.

Enhancements:

  • Expose SDK lifecycle primitives including closeItem, terminal transition policy, and reason/order governance as public API and update CLI to act as a thin compatibility shim.
  • Introduce terminal lifecycle policy primitives (reason resolution and ordering-edge handling) with a compilable SDK example and dedicated documentation.
  • Update error provenance, mocks, and tests so MCP, dedupe, and integration workflows consume the new SDK lifecycle modules consistently.

Documentation:

  • Add SDK lifecycle policy documentation and a compilable example demonstrating terminal reason and ordering-edge policy usage.

Tests:

  • Expand unit and integration coverage for terminal reason governance, predecessor preservation across lifecycle transitions, and SDK lifecycle policy primitives.

Summary by cubic

Moves terminal lifecycle to SDK-owned operations for consistent close behavior across CLI, SDK, and MCP. Fixes reason governance, preserves predecessor edges, and hardens close provenance (keeps existing reasons and normalizes ids) to keep project history intact. Addresses pm-2ew0w3 and pm-xm0id4; advances pm-z5pmf8.

  • Bug Fixes

    • Enforce close_reason_required across direct close, update --status closed, and direct terminal create; no synthesized reasons, and existing reasons are never overwritten.
    • Normalize canonical ids on input (accept ids with or without the pm- prefix) and clear only transient blocked state while preserving blocked_by edges through close → reopen → reclose.
    • Surface reason provenance via resolveTerminalReason/requireTerminalReason; update tests and runtime contracts to assert ordering survival and provenance.
  • Migration

    • SDK: use closeItem/runClose plus requireTerminalReason, applyTerminalOrderingPolicy, and TerminalTransitionPolicy from @unbrained/pm-cli/sdk.
    • CLI: when using pm create --status closed or pm update --status closed, pass a reason via --close-reason or --message; reasonless transitions now fail with close_reason_required under governance. Expect blocked_by edges to remain after close.

Written for commit 43dc0e0. Summary will update on new commits.

Review in cubic

Move the close transaction behind public SDK operation contracts, centralize author-controlled terminal reason governance across create/update/close routes, and retain predecessor dependencies across close/reopen cycles. Add SDK documentation, executable examples, complete regression coverage, public-surface provenance, PM evidence, and generated changelog entries for pm-z5pmf8, pm-xm0id4, and pm-2ew0w3.
@gemini-code-assist

Copy link
Copy Markdown

Caution

The consumer version of Gemini Code Assist on GitHub has been sunset. All code review activity has officially ceased.

@sourcery-ai sourcery-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Sorry @unbraind, you have reached your weekly rate limit of 500000 diff characters.

Please try again later or upgrade to continue using Sourcery

@unbraind

Copy link
Copy Markdown
Owner Author

@greptileai please review this exact head. @coderabbitai full review

@coderabbitai

coderabbitai Bot commented Jul 31, 2026 •

Copy link
Copy Markdown

@unbraind: I will perform a full review of the current PR head.

✅ Action performed

Full review finished.


Your included review limit is currently reached under our Fair Usage Limits Policy. This review may still proceed through usage-based billing if eligible. Your next included review will be available in 59 minutes.

@coderabbitai

coderabbitai Bot commented Jul 31, 2026 •

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

@unbraind, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 38 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

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 configuration

Configuration used: Repository UI (base), Organization UI (inherited)

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 9908a036-34be-44eb-be34-b5c7df831452

📥 Commits

Reviewing files that changed from the base of the PR and between 67cac2b and 43dc0e0.

📒 Files selected for processing (32)
  • .agents/pm/history/pm-2ew0w3.jsonl
  • .agents/pm/history/pm-xm0id4.jsonl
  • .agents/pm/history/pm-z5pmf8.jsonl
  • .agents/pm/issues/pm-2ew0w3.toon
  • .agents/pm/issues/pm-xm0id4.toon
  • .agents/pm/issues/pm-z5pmf8.toon
  • CHANGELOG.md
  • docs/SDK_LIFECYCLE.md
  • docs/examples/sdk-lifecycle-policy/index.ts
  • sdk/public-surface.json
  • src/cli/commands/close.ts
  • src/cli/commands/create.ts
  • src/cli/commands/update.ts
  • src/core/shared/constants.ts
  • src/sdk/cli-contracts/typed-action-inputs.ts
  • src/sdk/generated-error-code-catalog.ts
  • src/sdk/index.ts
  • src/sdk/lifecycle-policy.ts
  • src/sdk/lifecycle/close.ts
  • src/sdk/runtime.ts
  • tests/fixtures/contracts/full.json
  • tests/integration/cli.integration.spec.ts
  • tests/integration/duplicates-command.integration.spec.ts
  • tests/integration/mcp-dynamic-package-actions.spec.ts
  • tests/integration/release-readiness-runtime.spec.ts
  • tests/unit/commands/close-command.spec.ts
  • tests/unit/commands/create-command.spec.ts
  • tests/unit/commands/dedupe-merge-command.spec.ts
  • tests/unit/commands/update-command.spec.ts
  • tests/unit/mcp/mcp-server-branch-residual.spec.ts
  • tests/unit/sdk/lifecycle-policy.spec.ts
  • tests/unit/sdk/sdk-index.spec.ts
📝 Walkthrough

Summary by CodeRabbit

  • New Features
    • Added shared lifecycle controls for terminal transitions across supported interfaces.
    • Added SDK APIs for close operations, reason resolution, and ordering policies.
    • Closing items now preserves ordering relationships while clearing temporary blocking status.
  • Bug Fixes
    • Reasonless close transitions now fail with a clear close_reason_required error instead of applying a default reason.
    • Close, reopen, and reclose cycles retain predecessor relationships.
  • Documentation
    • Added lifecycle-policy guidance and usage examples.
  • Tests
    • Expanded coverage for reason validation and ordering behavior.

Walkthrough

The PR moves close handling into the SDK, enforces author-controlled terminal reasons, preserves or removes ordering edges through policy, updates CLI and MCP integrations, expands public exports, and adds documentation and regression coverage.

Changes

Terminal lifecycle governance

Layer / File(s) Summary
Lifecycle policy contracts and public surface
src/sdk/lifecycle-policy.ts, sdk/public-surface.json, docs/SDK_LIFECYCLE.md, docs/examples/sdk-lifecycle-policy/*, tests/unit/sdk/lifecycle-policy.spec.ts
Adds terminal reason resolution, required-reason enforcement, ordering-edge policies, public SDK types and exports, documentation, examples, and policy tests.
SDK close implementation and compatibility wiring
src/sdk/lifecycle/close.ts, src/sdk/runtime.ts, src/cli/commands/close.ts, src/sdk/generated-error-code-catalog.ts, src/sdk/cli-contracts/typed-action-inputs.ts
Moves close execution into the SDK and preserves CLI compatibility through re-exports. The close flow validates targets, mutates terminal metadata, handles duplicates, clears transient blockers, and auto-unblocks eligible dependents.
CLI route integration and lifecycle regression coverage
src/cli/commands/create.ts, src/cli/commands/update.ts, tests/integration/*, tests/unit/commands/*, tests/unit/mcp/*, .agents/pm/*, CHANGELOG.md
Routes terminal creation and updates through shared reason enforcement. Tests cover rejected reasonless transitions, explicit fixture reasons, and preservation of blocked_by edges across close and reopen cycles.

Estimated code review effort: 4 (Complex) | ~60 minutes

Sequence Diagram(s)

sequenceDiagram
  participant CLI
  participant MCP
  participant lifecycleClose
  participant lifecyclePolicy
  participant ItemStore
  CLI->>lifecycleClose: Route terminal close
  MCP->>lifecycleClose: Route terminal close
  lifecycleClose->>lifecyclePolicy: Resolve and require terminal reason
  lifecycleClose->>ItemStore: Apply terminal metadata and ordering policy
  ItemStore-->>lifecycleClose: Updated item and warnings
  lifecycleClose-->>CLI: Close result
  lifecycleClose-->>MCP: Close result
Loading

Possibly related PRs

  • unbraind/pm-cli#456: Introduced related SDK lifecycle exports that this PR extends with terminal policy APIs.
  • unbraind/pm-cli#230: Modified close-reason derivation that this PR replaces with SDK enforcement.
  • unbraind/pm-cli#37: Added blocked_by edges whose terminal preservation is governed by this PR.
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 30.43% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Title check ✅ Passed The title clearly summarizes the main change: moving terminal lifecycle policy into the SDK and preserving project history.
Description check ✅ Passed The description directly explains the lifecycle changes, governance fixes, durable ordering edges, documentation, and verification.
✨ Finishing Touches 💡 2
📝 Generate docstrings 💡
  • Create stacked PR
  • Commit on current branch
🛠️ Fix failing CI checks 💡
  • Fix failing CI checks

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@sourcery-ai

sourcery-ai Bot commented Jul 31, 2026

Copy link
Copy Markdown

Reviewer's Guide

This PR centralizes terminal lifecycle policy in the SDK, introduces public primitives for terminal reasons and predecessor-edge handling, and updates CLI/MCP paths and tests so all terminal transitions share the same reason governance and preserve historical ordering edges by default.

Sequence diagram for SDK-owned closeItem operation

sequenceDiagram
  participant Caller as PresentationSurface
  participant Close as closeItem
  participant Runtime as runtime_primitives
  participant Policy as lifecycle_policy
  participant Store as Filesystem

  Caller->>Close: closeItem(id, closeReasonText, options, global)
  Close->>Runtime: resolvePmRoot, getSettingsPath, pathExists
  Close->>Runtime: readSettings
  Close->>Runtime: resolveRuntimeStatusRegistry
  Close->>Runtime: resolveAuthor
  Close->>Runtime: resolveItemTypeRegistry
  Close->>Runtime: locateItem
  alt item_not_found
    Close->>Caller: throw buildItemNotFoundError
  end

  Close->>Runtime: readLocatedItem (via assertDuplicateTargetExists)
  Close->>Policy: requireTerminalReason({explicit, duplicateOf, resolution, message}, requireCloseReason)
  Close->>Runtime: resolveIsoOrRelative(completedAt)

  Close->>Runtime: mutateItem(op="close", mutate)
  activate Runtime
    Runtime->>Policy: applyTerminalOrderingPolicy(metadata, lifecyclePolicy)
  deactivate Runtime

  Runtime-->>Close: {item, changedFields, warnings}
  Close->>Runtime: listAllItemMetadataLight (autoUnblockResolvedDependents)
  Close->>Runtime: mutateItem(op="update")

  Close-->>Caller: CloseOperationResult{item, changed_fields, warnings}
Loading

File-Level Changes

Change Details Files
Move close lifecycle implementation from CLI into SDK and expose command-shaped and SDK-shaped close APIs.
  • Reimplemented the close command logic as sdk/lifecycle/close.ts, retaining runtime behavior and validation while making it SDK-owned.
  • Turned src/cli/commands/close.ts into a thin compatibility shim that re-exports closeItem/runClose and related types from the SDK lifecycle module.
  • Updated sdk/runtime.ts, sdk/index.ts, typed-action-inputs, MCP server tests, dedupe-merge tests, and SDK index tests to import and mock the new SDK lifecycle APIs instead of the CLI module.
src/cli/commands/close.ts
src/sdk/lifecycle/close.ts
src/sdk/runtime.ts
src/sdk/index.ts
src/sdk/cli-contracts/typed-action-inputs.ts
tests/unit/mcp/mcp-server-branch-residual.spec.ts
tests/unit/commands/dedupe-merge-command.spec.ts
tests/unit/sdk/sdk-index.spec.ts
Introduce terminal lifecycle policy primitives (reason resolution and ordering edges) as a public SDK surface.
  • Added src/sdk/lifecycle-policy.ts defining TerminalTransitionPolicy, TerminalReasonInput/Resolution, CloseOperationOptions/Result, DEFAULT_TERMINAL_TRANSITION_POLICY, resolveTerminalReason, requireTerminalReason, and applyTerminalOrderingPolicy.
  • Exported lifecycle-policy primitives through sdk/runtime.ts and sdk/index.ts, and documented them in docs/SDK_LIFECYCLE.md plus a compilable example in docs/examples/sdk-lifecycle-policy/index.ts.
  • Added unit coverage for lifecycle-policy behavior in tests/unit/sdk/lifecycle-policy.spec.ts and wired the example into tests to ensure it compiles and runs.
src/sdk/lifecycle-policy.ts
src/sdk/runtime.ts
src/sdk/index.ts
docs/SDK_LIFECYCLE.md
docs/examples/sdk-lifecycle-policy/index.ts
tests/unit/sdk/lifecycle-policy.spec.ts
Align all terminal routes (close, update --status closed, create --status closed) on a single reason-governance contract that never synthesizes immutable reasons.
  • Refactored closeItem/runClose to use requireTerminalReason and lifecyclePolicy overrides, so governance.require_close_reason applies consistently and reasons are derived only from author-controlled fields.
  • Updated src/cli/commands/update.ts to route status=closed through SDK runClose using the caller-provided reason (or none), removing the previous auto-defaulted "Closed via pm update" behavior.
  • Updated src/cli/commands/create.ts to use requireTerminalReason in resolveCreateCloseReason, failing direct terminal creation without a reason instead of defaulting a placeholder; kept CREATE_DIRECT_CLOSE_REASON_DEFAULT as deprecated for compatibility.
  • Adjusted unit tests for update, create, and release-readiness to expect close_reason_required failures when no reason is supplied, and to verify successful closes when a message is provided.
  • Regenerated the error catalog to point close_reason_required and related duplicate-target errors at the new SDK lifecycle modules.
src/sdk/lifecycle/close.ts
src/sdk/lifecycle-policy.ts
src/cli/commands/update.ts
src/cli/commands/create.ts
src/core/shared/constants.ts
src/sdk/generated-error-code-catalog.ts
tests/unit/commands/update-command.spec.ts
tests/unit/commands/create-command.spec.ts
tests/integration/release-readiness-runtime.spec.ts
Preserve predecessor (blocked_by) dependency edges through close/reopen/reclose while clearing only transient blocked state, and adjust unblocking behavior accordingly.
  • Changed close mutation logic to delegate blocked-state handling to applyTerminalOrderingPolicy, which clears blocked_by and blocked_reason scalars but preserves blocked_by dependency rows under the default policy.
  • Updated close command unit tests to assert that dependencies with kind=blocked_by are retained on close, reopen, and reclose cycles, and that warnings now report closed_preserved_predecessors instead of closed_cleared_blocked_by.
  • Ensured mixed dependency sets keep both predecessor and non-blocking edges, and that auto-unblock logic continues to clear dependencies and scalars when dependents transition back to open.
  • Updated duplicates and integration fixtures to provide explicit messages when creating closed items to satisfy the new reason requirements.
src/sdk/lifecycle/close.ts
src/sdk/lifecycle-policy.ts
tests/unit/commands/close-command.spec.ts
tests/unit/commands/dedupe-merge-command.spec.ts
tests/integration/duplicates-command.integration.spec.ts
tests/integration/cli.integration.spec.ts
tests/integration/mcp-dynamic-package-actions.spec.ts
Surface the new lifecycle primitives and behaviors in SDK/CLI documentation, public-surface metadata, and changelog.
  • Added SDK_LIFECYCLE.md describing terminal reason precedence, governance enforcement, ordering-edge policy, and SDK ownership of lifecycle semantics.
  • Registered lifecycle-policy exports and closeItem in sdk/public-surface.json and sdk index/runtime exports, preserving API classification.
  • Extended CHANGELOG.md with entries for the fixed governance divergence between pm close and pm update --status closed, and the preservation of historical ordering edges.
  • Updated PM lineage history/issue files to reflect completion status of pm-2ew0w3 and pm-xm0id4 and in-progress work for pm-z5pmf8.
docs/SDK_LIFECYCLE.md
docs/examples/sdk-lifecycle-policy/index.ts
sdk/public-surface.json
CHANGELOG.md
.agents/pm/history/pm-2ew0w3.jsonl
.agents/pm/history/pm-xm0id4.jsonl
.agents/pm/history/pm-z5pmf8.jsonl
.agents/pm/issues/pm-2ew0w3.toon
.agents/pm/issues/pm-xm0id4.toon
.agents/pm/issues/pm-z5pmf8.toon

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

@codspeed

codspeed Bot commented Jul 31, 2026 •

Copy link
Copy Markdown

Merging this PR will not alter performance

✅ 11 untouched benchmarks


Comparing feat/sdk-lifecycle-policy (43dc0e0) with main (67cac2b)

Open in CodSpeed

@codecov

codecov Bot commented Jul 31, 2026 •

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ All tests successful. No failed tests found.

📢 Thoughts on this report? Let us know!

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 9

🤖 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 @.agents/pm/issues/pm-2ew0w3.toon:
- Around line 33-39: Update the owning item pm-2ew0w3 through pm files to
include all six listed source and test paths, ensuring every change is linked.
Then verify the live record state and confirm the table-driven terminal-route
acceptance criterion includes the negative control for a terminal route that
skips rule-set evaluation.

In `@src/sdk/index.ts`:
- Line 460: Update sdk/public-surface.json to record the public symbols exported
by lifecycle-policy.ts, matching the re-export added in src/sdk/index.ts.
Include all newly exposed lifecycle policy symbols so the recorded SDK surface
stays synchronized with the public exports.

In `@src/sdk/lifecycle-policy.ts`:
- Around line 164-176: Update the blocked_by cleanup in the lifecycle transition
to check field presence rather than the trimmed previousBlockedBy value. Use
metadata.blocked_by !== undefined for the deletion and changedFields update,
while retaining previousBlockedBy for any existing normalized-value logic.

In `@src/sdk/lifecycle/close.ts`:
- Around line 298-311: Update closeItem to call listAllItemMetadataLight once
and pass the resulting metadata collection into both findActiveChildIds and
findAutoUnblockCandidates. Refactor those helpers to accept and reuse the
preloaded items instead of performing their own tracker scans, preserving their
existing filtering and unblock behavior.
- Around line 518-531: Update applyCloseReason so an undefined closeReason
preserves any existing metadata.close_reason and does not delete it; only apply
and report close_reason when a new reason is supplied, while retaining the
empty-change result when neither value exists.
- Around line 671-687: Update the closeReason construction in the lifecycle
close flow to always pass options.message to requireTerminalReason, regardless
of lifecyclePolicy.requireCloseReason. Keep the policy flag controlling whether
a reason is required, but ensure author-provided message text remains available
as closure evidence when the requirement is disabled.
- Around line 694-699: Use the canonical identifier returned by locateItem
throughout close validation: pass located.id to findActiveChildIds and use it as
closingId for assertDuplicateTargetExists and circular-chain checks. Keep the
existing located.id usage at the later validation site consistent so child,
duplicate, and cycle comparisons match stored canonical item IDs.

In `@tests/integration/release-readiness-runtime.spec.ts`:
- Around line 2536-2543: Update the assertions in the auto-route close test
around autoRouteJson to verify that item.close_reason equals the author-supplied
message and that warnings does not contain "close_reason_defaulted", while
preserving the existing closed-status and auto-route warning assertions.

In `@tests/unit/commands/close-command.spec.ts`:
- Around line 1202-1253: Extend the acceptance coverage around the existing
predecessor-history test and the relevant close/status-update flows: verify that
update --status closed auto-routes through the same preservation behavior, and
add a corpus-level assertion that blocked_by relationships survive at the rate
required by pm-xm0id4. Ensure the checks also cover clearClosedBlockerSignals
removing blocked_by rows from closed items, or adjust the implementation to
satisfy those criteria while preserving the existing reclose assertions.
🪄 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: Repository UI (base), Organization UI (inherited)

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 62dcbdc7-eadb-43bf-97be-46730d33a510

📥 Commits

Reviewing files that changed from the base of the PR and between 67cac2b and 9c75b5b.

📒 Files selected for processing (31)
  • .agents/pm/history/pm-2ew0w3.jsonl
  • .agents/pm/history/pm-xm0id4.jsonl
  • .agents/pm/history/pm-z5pmf8.jsonl
  • .agents/pm/issues/pm-2ew0w3.toon
  • .agents/pm/issues/pm-xm0id4.toon
  • .agents/pm/issues/pm-z5pmf8.toon
  • CHANGELOG.md
  • docs/SDK_LIFECYCLE.md
  • docs/examples/sdk-lifecycle-policy/index.ts
  • sdk/public-surface.json
  • src/cli/commands/close.ts
  • src/cli/commands/create.ts
  • src/cli/commands/update.ts
  • src/core/shared/constants.ts
  • src/sdk/cli-contracts/typed-action-inputs.ts
  • src/sdk/generated-error-code-catalog.ts
  • src/sdk/index.ts
  • src/sdk/lifecycle-policy.ts
  • src/sdk/lifecycle/close.ts
  • src/sdk/runtime.ts
  • tests/integration/cli.integration.spec.ts
  • tests/integration/duplicates-command.integration.spec.ts
  • tests/integration/mcp-dynamic-package-actions.spec.ts
  • tests/integration/release-readiness-runtime.spec.ts
  • tests/unit/commands/close-command.spec.ts
  • tests/unit/commands/create-command.spec.ts
  • tests/unit/commands/dedupe-merge-command.spec.ts
  • tests/unit/commands/update-command.spec.ts
  • tests/unit/mcp/mcp-server-branch-residual.spec.ts
  • tests/unit/sdk/lifecycle-policy.spec.ts
  • tests/unit/sdk/sdk-index.spec.ts

Comment thread .agents/pm/issues/pm-2ew0w3.toon Resolved
Comment thread src/sdk/index.ts Resolved
Comment thread src/sdk/lifecycle-policy.ts Resolved
Comment thread src/sdk/lifecycle/close.ts Resolved
Comment thread src/sdk/lifecycle/close.ts Resolved
Comment thread src/sdk/lifecycle/close.ts Resolved
Comment thread src/sdk/lifecycle/close.ts Resolved
Address exact-head review feedback by preserving existing reasons, normalizing canonical ids, clearing present blocked scalars, sharing the tracker scan, proving update-route and corpus ordering survival, asserting reason provenance, and regenerating the runtime contract fixture. Record review evidence on the canonical PM lineage.
@unbraind

Copy link
Copy Markdown
Owner Author

Bot review acknowledgements for exact head 43dc0e0: Gemini sunset notice was accurate but informational; Sourcery was down-voted because its rate-limit response contained no review; CodeRabbit invocation, walkthrough, and nine findings were usefulness-voted and each inline thread received a specific verification or fix response. All actionable findings are covered by 6,613 passing tests at 100/100/100/100.

@unbraind

Copy link
Copy Markdown
Owner Author

@greptileai please re-review exact head 43dc0e0 after the review fixes. @coderabbitai full review

@coderabbitai

coderabbitai Bot commented Jul 31, 2026 •

Copy link
Copy Markdown

@unbraind: I will perform a full review of PR #846 at commit 43dc0e0f78ca419d0c4b47ae58536f9c56eddde1.

✅ Action performed

Full review finished.


Your included review limit is currently reached under our Fair Usage Limits Policy. This review may still proceed through usage-based billing if eligible. Your next included review will be available in 38 minutes.

@unbraind

Copy link
Copy Markdown
Owner Author

Final review-loop acknowledgement for exact head 43dc0e0: all nine CodeRabbit threads are resolved and their confirmation replies/reviews were usefulness-voted. Sourcery reviewer guidance was also acknowledged; its sequence description predates the follow-up optimization, where closeItem now performs one metadata scan, and pm-z5pmf8 is open and unclaimed. Required checks are terminal green with no failed checks.

@unbraind
unbraind merged commit b7651d7 into main Jul 31, 2026
32 checks passed
@unbraind
unbraind deleted the feat/sdk-lifecycle-policy branch July 31, 2026 16:17
@unbraind

unbraind commented Aug 4, 2026

Copy link
Copy Markdown
Owner Author

Tracked in PM: pm-2ew0w3, pm-xm0id4, pm-z5pmf8.

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.

1 participant