Skip to content

PAN-3552 - #3573

Merged
overdeck-agent[bot] merged 22 commits into
mainfrom
feature/pan-3552
Aug 5, 2026
Merged

PAN-3552#3573
overdeck-agent[bot] merged 22 commits into
mainfrom
feature/pan-3552

Conversation

@eltmon

@eltmon eltmon commented Aug 5, 2026

Copy link
Copy Markdown
Owner

Issue: #3552

Acceptance Criteria

  • Spawn the convoy inline at dispatch — remove the parent's discovery phase
  • Remove the reviewer session fork and rename the recovery entry point
  • Remove the pan admin specialists discovery-ready verb
  • Delete the stalled-discovery backstop and the fork cache-miss detector
  • Remove the five fork-only AgentState fields from every read and write path
  • Run all four reviewers every cycle — delete the re-review selection logic
  • Remove the reviewerVerdicts map from status, the write door, and the durable record
  • Remove the reReviewScope setting from config, API, CLI, and both UI surfaces
  • Delete the branch-invalidation patrol
  • Remove the conflictsSince field and its parked orbit
  • Remove the stall sweeper's residual actor event surface
  • Converge the row from the verdict of record before a dispatch writes reviewing
  • Reconcile reviewing rows that already have a verdict on disk
  • Stop re-gating a test verdict recorded at the same head
  • Rewrite the review architecture doc to the simplified flow
  • Update the parked, merge, and flywheel docs for the removed layers

Summary by CodeRabbit

  • New Features

    • Review workflows now launch independent reviewer lanes and recover missing reviewers automatically.
    • Review verdicts support safer evidence validation, including multi-repository review contexts.
    • Durable review dispatch and feedback delivery improve recovery of completed review results.
  • Changes

    • Removed per-issue re-review scope configuration and related CLI options.
    • After merges, branches must be explicitly updated with pan sync-main.
    • Parked-issue classification now contains nine categories; conflict entries are no longer classified.
    • God View updates parked data only after population-changing scans and uses clearer sweep animations.
  • Documentation

    • Updated review, merge, monitoring, and architecture guidance to reflect the streamlined workflow.

panopticon-agent[bot] and others added 18 commits August 5, 2026 11:03
Co-Authored-By: Claude <noreply@anthropic.com>
Co-Authored-By: Claude <noreply@anthropic.com>
Co-Authored-By: Claude <noreply@anthropic.com>
Co-Authored-By: Claude <noreply@anthropic.com>
Co-Authored-By: Claude <noreply@anthropic.com>
Co-Authored-By: Claude <noreply@anthropic.com>
Co-Authored-By: Claude <noreply@anthropic.com>
Co-Authored-By: Claude <noreply@anthropic.com>
Co-Authored-By: Claude <noreply@anthropic.com>
Co-Authored-By: Claude <noreply@anthropic.com>
Co-Authored-By: Claude <noreply@anthropic.com>
Co-Authored-By: Claude <noreply@anthropic.com>
Co-Authored-By: Claude <noreply@anthropic.com>
Co-Authored-By: Claude <noreply@anthropic.com>
Co-Authored-By: Claude <noreply@anthropic.com>
Co-Authored-By: Claude <noreply@anthropic.com>
Co-Authored-By: Claude <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Aug 5, 2026

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

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

Next review available in: 21 minutes

You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository.

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: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: b57c3c4c-8e3e-429d-9f15-ccd656113904

📥 Commits

Reviewing files that changed from the base of the PR and between 9ef214d and 35d7780.

📒 Files selected for processing (13)
  • src/dashboard/frontend/src/components/GodView/confluence/__tests__/useConfluenceData.test.ts
  • src/dashboard/frontend/src/components/GodView/confluence/useConfluenceData.ts
  • src/lib/cloister/__tests__/review-agent.test.ts
  • src/lib/cloister/__tests__/review-verdict-writer.test.ts
  • src/lib/cloister/__tests__/stall-sweeper.test.ts
  • src/lib/cloister/review-agent.ts
  • src/lib/cloister/review-verdict-writer.ts
  • src/lib/cloister/stall-sweeper-state.ts
  • src/lib/cloister/stall-sweeper.ts
  • src/lib/parked/__tests__/resolver.test.ts
  • src/lib/parked/resolver.ts
  • tests/unit/cli/parked-ack.test.ts
  • tests/unit/lib/head-anchor-write-sites.test.ts
📝 Walkthrough

Walkthrough

This PR simplifies review execution around standard convoy lanes and centralized verdict recording. It removes discovery, fork, selective re-review, reviewer-verdict, branch-invalidation, and conflict-orbit mechanisms. It also updates durable state, configuration APIs, sweep events, recovery, tests, and documentation.

Changes

Review pipeline and verdict recovery

Layer / File(s) Summary
Direct convoy dispatch and recovery
src/lib/cloister/review-agent.ts, src/lib/cloister/review-convoy.ts, src/lib/cloister/deacon-review-signals.ts
Full reviews launch standard reviewer lanes. Synthesis waits for all lane reports. Missing lanes recover without forked sessions or carried verdicts.
Canonical verdict convergence
src/lib/cloister/verdict-restore.ts, src/lib/cloister/review-verdict-writer.ts, src/lib/cloister/deacon-review-unsignaled.ts
Recovery validates run IDs, artifact freshness, head anchors, and workspace heads before calling recordReviewVerdict().
Review status and host integration
src/lib/review-status.ts, src/lib/cloister/work-start-verdicts.ts, src/lib/cloister/durable-review-pipeline.ts, src/lib/cloister/review-verdict-feedback.ts
Registered adapters now handle verdict preservation, durable dispatch, post-merge state, and blocked or failed feedback delivery.

Configuration and state cleanup

Layer / File(s) Summary
Review configuration removal
src/cli/commands/review-subcommands.ts, src/dashboard/server/routes/workspaces/review-control.ts, src/dashboard/frontend/src/components/IssuePolicyStrip.tsx, src/lib/config-yaml/*
The review scope command and reReviewScope configuration are removed from CLI, API, dashboard, and YAML handling.
Durable status and agent metadata
src/lib/review-status-types.ts, src/lib/overdeck/*, src/lib/pan-dir/*, drizzle/overdeck/0000_overdeck_init.sql
Shared status types are introduced. reviewerVerdicts, conflictsSince, and obsolete discovery or fork fields are removed from durable projections and agent persistence.
Validation coverage
tests/unit/lib/*, src/lib/cloister/__tests__/*, src/dashboard/*/__tests__/*
Tests cover verdict convergence, recovery boundaries, dispatcher registration, configuration responses, and updated persistence rules.

Sweep and merge behavior

Layer / File(s) Summary
Sweep event contracts and choreography
packages/contracts/src/events.ts, packages/contracts/src/events.test.ts, src/dashboard/frontend/src/components/GodView/confluence/*
sweep.scan remains supported. Retired sweep action and unparked events are rejected. Parked data refreshes only after scan population changes.
Parked and branch reconciliation changes
src/lib/parked/resolver.ts, src/lib/cloister/deacon.ts, src/lib/cloister/stall-sweeper.ts, src/lib/cloister/branch-invalidation.ts
The conflicts orbit and branch-invalidation patrol are removed. Stall sweeping reports recommendations without autonomous un-parking actions.
Operational documentation
docs/*, CLAUDE.md
Documentation describes explicit pan sync-main handling, direct convoy review flow, revised sweep behavior, and the nine-orbit taxonomy.

Estimated code review effort: 5 (Critical) | ~120 minutes

Possibly related issues

Possibly related PRs

  • eltmon/overdeck#3514 — Both changes modify centralized verdict writing and dispatched verdict events.
  • eltmon/overdeck#3529 — Both changes modify verdict restoration and review-recovery behavior.
  • eltmon/overdeck#3136 — Both changes modify reviewed workspace-head preservation and pipeline verdict reset handling.
🚥 Pre-merge checks | ✅ 3 | ❌ 2

❌ Failed checks (1 warning, 1 inconclusive)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 38.81% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
Title check ❓ Inconclusive The title contains only the issue identifier and does not describe the review and dispatch architecture changes. Replace PAN-3552 with a concise title that states the primary review and dispatch architecture simplification.
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
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.
✨ Finishing Touches 💡 1
📝 Generate docstrings 💡
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feature/pan-3552

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.

@eltmon

eltmon commented Aug 5, 2026

Copy link
Copy Markdown
Owner Author

Review CHANGES REQUESTED for PAN-3552

Review Synthesis — PAN-3552 — 2026-08-05T15:38:15-04:00

Verdict: CHANGES REQUESTED — removing resolveReReviewScope leaves the live per-issue review-config API throwing

Context

  • Manifest: /home/eltmon/Projects/overdeck/workspaces/feature-pan-3552/.pan/review/agent-pan-3552-review-d09c573f/context.json
  • Branch: feature/pan-3552
  • Workspace: /home/eltmon/Projects/overdeck/workspaces/feature-pan-3552
  • HEAD reviewed: d09c573f9177d5775d56e4bce3844e7bae066636
  • PR base: c3cf20667708989489a34a6b3a68ae36f49d2cfc
  • Cycle number: 1
  • Prior cycle SHA: none

Convoy Status

Sub-role Signal Output Blocking findings
security ready /home/eltmon/Projects/overdeck/workspaces/feature-pan-3552/.pan/review/agent-pan-3552-review-d09c573f/security.md 0
correctness ready /home/eltmon/Projects/overdeck/workspaces/feature-pan-3552/.pan/review/agent-pan-3552-review-d09c573f/correctness.md 2
performance ready /home/eltmon/Projects/overdeck/workspaces/feature-pan-3552/.pan/review/agent-pan-3552-review-d09c573f/performance.md 0
requirements ready /home/eltmon/Projects/overdeck/workspaces/feature-pan-3552/.pan/review/agent-pan-3552-review-d09c573f/requirements.md 2

Blocking Findings

[correctness, requirements] Removing resolveReReviewScope leaves a live API caller broken — src/lib/cloister/review-agent.ts:827

The changed export surface removes resolveReReviewScope, while the still-live GET and POST /api/review/:issueId/config route dynamically imports and calls it at src/dashboard/server/routes/workspaces/review-control.ts:680, :686, :726, and :746. Each route reaches TypeError: resolveReReviewScope is not a function. The same route also accepts, persists, and returns the removed reReviewScope override, so FR-2's API-surface removal is incomplete.

Although the stale caller itself predates this branch, the behavior regression is introduced by the changed removal of its export and is directly within the PR's scope. Remove the obsolete API field and dynamic import, then add route coverage for both the GET and POST paths.

[correctness, requirements] conflictsSince remains an active parked condition — src/lib/parked/resolver.ts:344

The branch deliberately changes this PR-scoped code to retain historical conflictsSince markers as the conflicts parked orbit. That contradicts the requirement to remove conflicts-since plumbing and its parked orbit, and it violates the stated compatibility contract: legacy durable keys must be tolerated rather than projected into live pipeline behavior. Existing records with the marker will keep issues visibly parked after the branch-invalidation owner has been deleted.

Remove conflictsSince from the active review-status projection and classifyParked, including the conflicts orbit and its tests. Continue accepting old durable records without surfacing the legacy key as an active state.

Non-blocking Findings

[requirements] Stale branch-invalidation guidance — CLAUDE.md:615

The project guidance still claims the removed branch-invalidation Deacon sweep detects, marks, and notifies sibling branches, while the updated merge workflow now requires explicit pan sync-main. This file is outside the PR diff, so it is advisory under the scope gate, but it should be corrected with the functional fixes to keep future agents from relying on retired behavior.

Clean Sub-roles

  • security
  • performance

Source: /home/eltmon/Projects/overdeck/workspaces/feature-pan-3552/.pan/review/agent-pan-3552-review-d09c573f/synthesis.md

Required action

Fix every blocking review finding, commit the fixes, then re-request review with:

pan review request PAN-3552 -m "Fixed review issues"

@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: 5

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
src/lib/cloister/review-convoy.ts (1)

302-317: 🩺 Stability & Availability | 🟠 Major | ⚡ Quick win

Apply the memory-pressure gate before launching missing convoy reviewers.

recoverMissingConvoyReviewers() can call launchConvoyReviewersPromise() without checking the memory predicate. spawnRun()/spawnAgentWithoutConsentClaim() do not apply the RECOVERY gate for review sub-roles, and tryReserveAdvancingSlot() is not invoked here. Since this is autonomous recovery admission, defer missing reviewer lanes until assessMemoryPressure() reports RECOVERY/ok, or route this path through an existing dispatch admission primitive that does.

🤖 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 `@src/lib/cloister/review-convoy.ts` around lines 302 - 317, The
launchConvoyReviewersPromise recovery path must apply the memory-pressure
admission gate before spawning missing reviewer sub-roles. Update the recovery
flow, including recoverMissingConvoyReviewers or the launch entry point, to
defer launching until assessMemoryPressure reports RECOVERY/ok, or route it
through an existing dispatch primitive that enforces this gate; preserve normal
reviewer result handling after admission.

Source: Coding guidelines

src/lib/cloister/deacon-review-signals.ts (1)

217-244: 🩺 Stability & Availability | 🟠 Major | ⚡ Quick win

Do not terminate the synthesis agent when the verdict does not land.

recordReviewVerdict() can return landed: false for stale evidence or an unresolved workspace. Lines 225-244 then skip feedback but still kill the synthesis session and report a synthesized review. The issue remains reviewing without a live agent that can recover the rejected verdict.

Check outcome.landed before feedback, session termination, and the synthesized action. Keep the parent alive or start an explicit recovery path when the write is rejected.

🤖 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 `@src/lib/cloister/deacon-review-signals.ts` around lines 217 - 244, Gate the
feedback, synthesis-session termination, and synthesized-review action in the
flow around recordReviewVerdict on outcome.landed. When the verdict write is
rejected, preserve the parent session or invoke an explicit recovery path and
avoid reporting a synthesized review; only execute deliverReviewVerdictFeedback,
killSession, action creation, and logging after a landed outcome.
🧹 Nitpick comments (1)
src/dashboard/frontend/src/components/GodView/confluence/__tests__/choreography.test.ts (1)

278-285: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Assert the escalation effect in the dispatch test.

This test dispatches sweep.escalated, but it checks only playSweep and the absence of playThaw. Add an assertion for playFlare('PAN-2') so the dispatch-table contract is covered.

🤖 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
`@src/dashboard/frontend/src/components/GodView/confluence/__tests__/choreography.test.ts`
around lines 278 - 285, Update the test covering sweep observation dispatch to
assert that the escalated event invokes api.playFlare with 'PAN-2'. Keep the
existing playSweep and playThaw assertions unchanged.
🤖 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 `@docs/overdeck-remodel/investigations/review-state-audit.md`:
- Line 103: Update the later description around the durable-record field
discussion to remove the claim that reviewer_verdicts is a durable-record field
or pass-through. Keep the audit consistent with the reviewer_verdicts entry
stating that it has no schema, migration, or runtime state representation.

In `@src/lib/cloister/review-agent.ts`:
- Around line 483-493: Move the convergeRowFromVerdictOfRecord call ahead of the
live-session idempotency guard in the review dispatch flow, so a live same-run
parent with a fresh verdict artifact can converge before the existing early
return. Preserve the current successful convergence activity emission and
response, and add a regression test covering a live same-run parent, no newer
request, and a fresh artifact.

In `@src/lib/cloister/review-verdict-writer.ts`:
- Around line 159-163: Update the anchor-match branch in the review verdict
writer so the ReviewStatusUpdate also persists reviewedAtCommit as
input.evidenceHead when input.evidenceHead equals status.lastVerifiedCommit. Add
a regression assertion in the review verdict writer tests confirming the
same-anchor path stores the current reviewedAtCommit.

In `@src/lib/cloister/synthesis-verdict.ts`:
- Around line 67-75: Update the repository-head handling in the synthesis
verdict logic so an empty context.repos array falls through to the existing
single-repository headSha fallback instead of returning undefined. Only return
undefined for nonempty repos lists that contain invalid entries, and add a
regression case covering repos: [] with a populated headSha.

In `@src/lib/parked/resolver.ts`:
- Around line 344-350: Choose the contract that treats conflictsSince as
historical after blocker cleanup: remove the live conflicts orbit from
resolver.ts#L344-L350 while preserving the marker in history/details, update
resolver.ts#L29-L29 to describe that behavior, align
docs/PARKED-POPULATION.md#L33-L33 and `#L43-L45` with the actual orbit count and
taxonomy, update docs/PARKED-POPULATION.md#L129-L129, and revise
src/lib/parked/__tests__/resolver.test.ts#L135-L135 to verify marker retention
without expecting a parked conflicts row.

---

Outside diff comments:
In `@src/lib/cloister/deacon-review-signals.ts`:
- Around line 217-244: Gate the feedback, synthesis-session termination, and
synthesized-review action in the flow around recordReviewVerdict on
outcome.landed. When the verdict write is rejected, preserve the parent session
or invoke an explicit recovery path and avoid reporting a synthesized review;
only execute deliverReviewVerdictFeedback, killSession, action creation, and
logging after a landed outcome.

In `@src/lib/cloister/review-convoy.ts`:
- Around line 302-317: The launchConvoyReviewersPromise recovery path must apply
the memory-pressure admission gate before spawning missing reviewer sub-roles.
Update the recovery flow, including recoverMissingConvoyReviewers or the launch
entry point, to defer launching until assessMemoryPressure reports RECOVERY/ok,
or route it through an existing dispatch primitive that enforces this gate;
preserve normal reviewer result handling after admission.

---

Nitpick comments:
In
`@src/dashboard/frontend/src/components/GodView/confluence/__tests__/choreography.test.ts`:
- Around line 278-285: Update the test covering sweep observation dispatch to
assert that the escalated event invokes api.playFlare with 'PAN-2'. Keep the
existing playSweep and playThaw assertions unchanged.
🪄 Autofix

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: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 8aa4b3f8-7c06-4795-b716-f02c2ef658de

📥 Commits

Reviewing files that changed from the base of the PR and between c3cf206 and d09c573.

⛔ Files ignored due to path filters (1)
  • packages/contracts/src/composer-commands.generated.ts is excluded by !**/*.generated.*
📒 Files selected for processing (79)
  • docs/DEACON-HEALTH-MONITORING.md
  • docs/FLYWHEEL-STATE.md
  • docs/GOD-VIEW.md
  • docs/MERGE-TRAIN.md
  • docs/MERGE-WORKFLOW.md
  • docs/PARKED-POPULATION.md
  • docs/QUICK-REFERENCE.md
  • docs/REVIEW-AGENT-ARCHITECTURE.md
  • docs/ROLES.md
  • docs/overdeck-remodel/investigations/review-state-audit.md
  • drizzle/overdeck/0000_overdeck_init.sql
  • packages/contracts/src/events.test.ts
  • packages/contracts/src/events.ts
  • scripts/dashboard-types-baseline.txt
  • src/cli/commands/review-mode.ts
  • src/cli/commands/review-subcommands.ts
  • src/cli/commands/specialists/done.ts
  • src/cli/commands/specialists/index.ts
  • src/dashboard/frontend/src/App/hooks/useDesktopActivityNotifications.ts
  • src/dashboard/frontend/src/components/CommandDeck/ZoneCOverviewTabs/queries.ts
  • src/dashboard/frontend/src/components/GodView/confluence/__tests__/choreography.test.ts
  • src/dashboard/frontend/src/components/GodView/confluence/useConfluenceChoreography.ts
  • src/dashboard/frontend/src/components/GodView/confluence/useConfluenceData.ts
  • src/dashboard/frontend/src/components/IssuePolicyStrip.test.tsx
  • src/dashboard/frontend/src/components/IssuePolicyStrip.tsx
  • src/dashboard/frontend/src/components/Settings/RolesPanel.tsx
  • src/dashboard/frontend/src/components/chat/__tests__/composerCommands.no-loss.test.ts
  • src/dashboard/frontend/src/components/chat/__tests__/slashCommands.no-loss.test.ts
  • src/dashboard/server/routes/admin.ts
  • src/dashboard/server/routes/context.ts
  • src/dashboard/server/routes/costs.ts
  • src/lib/__tests__/agent-state-role.test.ts
  • src/lib/__tests__/config-yaml-roles.test.ts
  • src/lib/__tests__/review-status-reconcile.test.ts
  • src/lib/agents/agent-state.ts
  • src/lib/agents/spawn-prep.ts
  • src/lib/agents/spawn.ts
  • src/lib/cloister/__tests__/deacon-stash-janitor.test.ts
  • src/lib/cloister/__tests__/review-rerun-scope.test.ts
  • src/lib/cloister/__tests__/review-verdict-writer.test.ts
  • src/lib/cloister/__tests__/synthesis-artifact-verdict.test.ts
  • src/lib/cloister/__tests__/verdict-restore.test.ts
  • src/lib/cloister/branch-invalidation.ts
  • src/lib/cloister/conflict-gate.ts
  • src/lib/cloister/deacon-post-review-commits.ts
  • src/lib/cloister/deacon-review-signals.ts
  • src/lib/cloister/deacon-review-unsignaled.ts
  • src/lib/cloister/deacon-review.ts
  • src/lib/cloister/deacon.ts
  • src/lib/cloister/review-agent.ts
  • src/lib/cloister/review-convoy.ts
  • src/lib/cloister/review-rerun-scope.ts
  • src/lib/cloister/review-verdict-writer.ts
  • src/lib/cloister/synthesis-verdict.ts
  • src/lib/cloister/verdict-restore.ts
  • src/lib/config-yaml/roles.ts
  • src/lib/config-yaml/schema.ts
  • src/lib/conversations/session-fork.ts
  • src/lib/conversations/summary-fork.ts
  • src/lib/overdeck/agent-state-sync.ts
  • src/lib/overdeck/agents.ts
  • src/lib/overdeck/infra.ts
  • src/lib/overdeck/review-status-record-sync.ts
  • src/lib/pan-dir/pipeline-verdict-merge.ts
  • src/lib/pan-dir/record.ts
  • src/lib/pan-dir/records.ts
  • src/lib/parked/__tests__/resolver.test.ts
  • src/lib/parked/resolver.ts
  • src/lib/review-status-reconcile.ts
  • src/lib/review-status.ts
  • src/lib/review-verdict-guards.ts
  • src/lib/settings-api.ts
  • tests/lib/cloister/review-agent.test.ts
  • tests/unit/lib/cloister/branch-invalidation.test.ts
  • tests/unit/lib/cloister/conflict-gate.test.ts
  • tests/unit/lib/cloister/deacon-post-blocked-review-commits.test.ts
  • tests/unit/lib/cloister/deacon-review-unapplied-verdicts.test.ts
  • tests/unit/lib/head-anchor-write-sites.test.ts
  • tests/unit/lib/overdeck/agent-discovery-columns.test.ts
💤 Files with no reviewable changes (22)
  • src/lib/agents/spawn-prep.ts
  • src/lib/cloister/deacon-review.ts
  • src/lib/pan-dir/records.ts
  • tests/unit/lib/cloister/deacon-post-blocked-review-commits.test.ts
  • drizzle/overdeck/0000_overdeck_init.sql
  • src/lib/cloister/tests/review-rerun-scope.test.ts
  • src/cli/commands/review-mode.ts
  • src/lib/agents/spawn.ts
  • src/lib/review-verdict-guards.ts
  • packages/contracts/src/events.ts
  • tests/unit/lib/head-anchor-write-sites.test.ts
  • src/lib/cloister/conflict-gate.ts
  • tests/unit/lib/cloister/branch-invalidation.test.ts
  • src/lib/cloister/review-rerun-scope.ts
  • src/lib/settings-api.ts
  • src/lib/overdeck/review-status-record-sync.ts
  • src/dashboard/frontend/src/components/Settings/RolesPanel.tsx
  • src/lib/config-yaml/schema.ts
  • src/lib/overdeck/agent-state-sync.ts
  • src/cli/commands/specialists/index.ts
  • src/lib/tests/review-status-reconcile.test.ts
  • src/lib/cloister/branch-invalidation.ts

| Listed | Reality |
| --- | --- |
| `reviewer_verdicts` | **Not a `review_status` column.** No CREATE TABLE entry, no migration, not in `DbReviewStatusRow`, not in the `ReviewStatus` interface. Exists ONLY as `reviewerVerdicts?: unknown` on the durable `PanIssuePipelineRecord` (record.ts:83), passed through at records.ts:110 via a cast that reads a property the source type doesn't even declare — so it is **always `undefined`** in practice. Dead pass-through. **DROP.** |
| `reviewer_verdicts` | **Not a `review_status` column.** It has no CREATE TABLE entry, migration, or runtime state field. The former durable pass-through was removed with the retired per-reviewer verdict state. |

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

Remove the stale durable-record description.

Line 103 says the reviewer_verdicts pass-through was removed. Lines 150-153 still describe it as a durable-record field. Update or remove that later description so this audit has one state model.

🤖 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 `@docs/overdeck-remodel/investigations/review-state-audit.md` at line 103,
Update the later description around the durable-record field discussion to
remove the claim that reviewer_verdicts is a durable-record field or
pass-through. Keep the audit consistent with the reviewer_verdicts entry stating
that it has no schema, migration, or runtime state representation.

Comment on lines +483 to +493
const convergence = await convergeRowFromVerdictOfRecord(opts.issueId, {
runId: getAgentStateSync(reviewSessionName)?.reviewRunId,
workspacePath: opts.workspace,
writer: 'dispatch-converge',
});
if (convergence.converged) {
const message = `Review dispatch converged from the verdict of record: ${opts.issueId}`;
emitActivityEntrySync({ source: 'review', level: 'info', message, issueId: opts.issueId });
return { success: true, message };
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Run verdict convergence before the live-session idempotency guard.

A same-run parent can stay live after it writes its report. If no newer request exists, Lines 388-400 leave finishedIdle false and Lines 415-418 return before this convergence call.

The valid artifact then remains unapplied and the review stays pending or reviewing. Move convergeRowFromVerdictOfRecord() before the liveness guard. Add a regression test with a live same-run parent, a fresh artifact, and no newer request.

🤖 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 `@src/lib/cloister/review-agent.ts` around lines 483 - 493, Move the
convergeRowFromVerdictOfRecord call ahead of the live-session idempotency guard
in the review dispatch flow, so a live same-run parent with a fresh verdict
artifact can converge before the existing early return. Preserve the current
successful convergence activity emission and response, and add a regression test
covering a live same-run parent, no newer request, and a fresh artifact.

Comment thread src/lib/cloister/review-verdict-writer.ts
Comment on lines +67 to +75
if (context.repos) {
const heads = context.repos.map(({ repoKey, headSha }) => (
typeof repoKey === 'string' && repoKey.length > 0 && typeof headSha === 'string' && headSha.length > 0
? `${repoKey}@${headSha}`
: null
));
if (heads.length > 0 && heads.every((head): head is string => head !== null)) return heads.join(' ');
return undefined;
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Preserve the single-repository fallback for an empty repos array.

An empty repos array enters this branch and returns undefined. It then skips the valid headSha fallback on Line 76. This prevents verdict recovery for contexts that serialize an empty optional repository list.

Only reject a nonempty invalid repository list. Let an empty array fall through to headSha. Add a regression case for { repos: [], headSha: "<sha>" }.

Proposed fix
-    if (context.repos) {
+    if (context.repos !== undefined) {
+      if (!Array.isArray(context.repos)) return undefined;
+      if (context.repos.length === 0) {
+        // Fall through to the single-repository headSha.
+      } else {
       const heads = context.repos.map(({ repoKey, headSha }) => (
         typeof repoKey === 'string' && repoKey.length > 0 && typeof headSha === 'string' && headSha.length > 0
           ? `${repoKey}@${headSha}`
           : null
       ));
       if (heads.length > 0 && heads.every((head): head is string => head !== null)) return heads.join(' ');
       return undefined;
+      }
     }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
if (context.repos) {
const heads = context.repos.map(({ repoKey, headSha }) => (
typeof repoKey === 'string' && repoKey.length > 0 && typeof headSha === 'string' && headSha.length > 0
? `${repoKey}@${headSha}`
: null
));
if (heads.length > 0 && heads.every((head): head is string => head !== null)) return heads.join(' ');
return undefined;
}
if (context.repos !== undefined) {
if (!Array.isArray(context.repos)) return undefined;
if (context.repos.length === 0) {
// Fall through to the single-repository headSha.
} else {
const heads = context.repos.map(({ repoKey, headSha }) => (
typeof repoKey === 'string' && repoKey.length > 0 && typeof headSha === 'string' && headSha.length > 0
? `${repoKey}@${headSha}`
: null
));
if (heads.length > 0 && heads.every((head): head is string => head !== null)) return heads.join(' ');
return undefined;
}
}
🤖 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 `@src/lib/cloister/synthesis-verdict.ts` around lines 67 - 75, Update the
repository-head handling in the synthesis verdict logic so an empty
context.repos array falls through to the existing single-repository headSha
fallback instead of returning undefined. Only return undefined for nonempty
repos lists that contain invalid entries, and add a regression case covering
repos: [] with a populated headSha.

Comment thread src/lib/parked/resolver.ts Outdated
Comment on lines +344 to +350
// 7. conflicts — retain historical conflict markers for the parked view.
if (!closed && r?.conflictsSince && r.mergeStatus !== 'merged') {
push(
'conflicts',
isoOr(r.conflictsSince.detectedAt, s.now),
`a merge to main invalidated this branch at ${r.conflictsSince.sha.slice(0, 10)} — conflict resolution was never completed`,
'kick off conflict resolution (sync-main / rebase) on a resumed work agent',
`a persisted conflict marker names ${r.conflictsSince.sha.slice(0, 10)}; this branch still needs rework`,
'resolve the recorded conflict, then submit the rework for review',

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🗄️ Data Integrity & Integration | 🟠 Major | 🏗️ Heavy lift

Choose one conflictsSince contract and apply it consistently.

tests/unit/lib/cloister/conflict-gate.test.ts retains conflictsSince after blocker cleanup, but the resolver still treats it as a live conflicts orbit while the parked documentation removes that orbit. This can keep an issue parked after its active blocker is cleared and makes the /api/parked contract inconsistent.

  • src/lib/parked/resolver.ts#L344-L350: classify only current conflict state, or remove this row and preserve the marker in history/details.
  • src/lib/parked/resolver.ts#L29-L29: describe the marker consistently with the chosen active-orbit behavior.
  • docs/PARKED-POPULATION.md#L33-L33: set the orbit count from the actual resolver taxonomy.
  • docs/PARKED-POPULATION.md#L43-L45: add or remove conflicts and renumber the remaining rows to match runtime output.
  • docs/PARKED-POPULATION.md#L129-L129: update the fixture statement after the contract is chosen.
  • src/lib/parked/__tests__/resolver.test.ts#L135-L135: test historical-marker retention without asserting a live parked row, or retain the assertion only if conflicts remains an active orbit.
📍 Affects 3 files
  • src/lib/parked/resolver.ts#L344-L350 (this comment)
  • src/lib/parked/resolver.ts#L29-L29
  • docs/PARKED-POPULATION.md#L33-L33
  • docs/PARKED-POPULATION.md#L43-L45
  • docs/PARKED-POPULATION.md#L129-L129
  • src/lib/parked/__tests__/resolver.test.ts#L135-L135
🤖 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 `@src/lib/parked/resolver.ts` around lines 344 - 350, Choose the contract that
treats conflictsSince as historical after blocker cleanup: remove the live
conflicts orbit from resolver.ts#L344-L350 while preserving the marker in
history/details, update resolver.ts#L29-L29 to describe that behavior, align
docs/PARKED-POPULATION.md#L33-L33 and `#L43-L45` with the actual orbit count and
taxonomy, update docs/PARKED-POPULATION.md#L129-L129, and revise
src/lib/parked/__tests__/resolver.test.ts#L135-L135 to verify marker retention
without expecting a parked conflicts row.

Co-Authored-By: Claude <noreply@anthropic.com>

@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: 2

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src/lib/cloister/conflict-gate.ts (1)

214-214: 🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win

Restore clearing of conflictsSince after a clean merge.

When clean-merge handling removes stale merge blockers, it must also clear conflictsSince. Otherwise, the durable status still satisfies the parked-state conflict classification, so legacy records continue to appear in the conflicts orbit after the blocker is gone. Restore the existing clear operation in the same status update while continuing to tolerate old records that already contain the field.

🤖 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 `@src/lib/cloister/conflict-gate.ts` at line 214, The clean-merge status update
must also clear conflictsSince when remainingBlockers is empty, while remaining
compatible with records where the field is absent. Restore the existing
conflictsSince-clearing operation alongside blockerReasons in the same status
update, preserving the current blocker behavior.
🤖 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
`@src/dashboard/server/routes/workspaces/__tests__/review-control-config-route.test.ts`:
- Around line 100-112: The review-control route tests only cover a
retired-field-only POST, not a mixed payload. Extend the relevant POST route
coverage around requestReviewConfig with a valid reviewMode or reviewModel plus
reReviewScope, and assert the retired field is omitted from both the persisted
updateIssueRecord call and the successful response. Add equivalent coverage for
both routes while preserving the existing validation behavior.

In `@src/lib/cloister/merge-agent.ts`:
- Around line 18-22: Update postMergeLifecycle() to make the handoff
non-destructive: remove agent pausing, work/reviewer and post-merge session
termination, and memory reset marker creation while preserving workspace, state,
xBRIEF, branches, agents, and sessions. Retain only the required Docker teardown
and ensure the related call sites and lifecycle flow no longer trigger those
destructive cleanup operations.

---

Outside diff comments:
In `@src/lib/cloister/conflict-gate.ts`:
- Line 214: The clean-merge status update must also clear conflictsSince when
remainingBlockers is empty, while remaining compatible with records where the
field is absent. Restore the existing conflictsSince-clearing operation
alongside blockerReasons in the same status update, preserving the current
blocker behavior.
🪄 Autofix

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: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 712dbabe-cb02-46fb-9577-196117f2c966

📥 Commits

Reviewing files that changed from the base of the PR and between d09c573 and 11bdaa3.

📒 Files selected for processing (38)
  • CLAUDE.md
  • scripts/circular-deps-baseline.txt
  • scripts/dashboard-types-baseline.txt
  • src/dashboard/server/routes/workspaces/__tests__/review-control-config-route.test.ts
  • src/dashboard/server/routes/workspaces/__tests__/review-pipeline-route.test.ts
  • src/dashboard/server/routes/workspaces/review-control.ts
  • src/dashboard/server/routes/workspaces/review-pipeline.ts
  • src/dashboard/server/services/durable-review-pipeline.ts
  • src/lib/__tests__/agents-spawn-supervisor.test.ts
  • src/lib/__tests__/review-status-reconcile.test.ts
  • src/lib/agents/spawn.ts
  • src/lib/cloister/__tests__/durable-review-pipeline.test.ts
  • src/lib/cloister/__tests__/review-agent.test.ts
  • src/lib/cloister/__tests__/stall-sweeper.test.ts
  • src/lib/cloister/__tests__/verdict-preservation.test.ts
  • src/lib/cloister/conflict-gate.ts
  • src/lib/cloister/durable-review-pipeline.ts
  • src/lib/cloister/merge-agent.ts
  • src/lib/cloister/post-merge-state.ts
  • src/lib/cloister/review-agent.ts
  • src/lib/cloister/review-verdict-feedback.ts
  • src/lib/cloister/stall-sweeper.ts
  • src/lib/cloister/verdict-preservation.ts
  • src/lib/cloister/work-start-verdicts.ts
  • src/lib/overdeck/review-status-record-sync.ts
  • src/lib/overdeck/review-status-sync.ts
  • src/lib/pan-dir/records.ts
  • src/lib/parked/__tests__/resolver.test.ts
  • src/lib/parked/resolver.ts
  • src/lib/pipeline-notifier.ts
  • src/lib/review-status-normalize.ts
  • src/lib/review-status-reconcile.ts
  • src/lib/review-status-types.ts
  • src/lib/review-status.ts
  • tests/lib/cloister/review-agent.test.ts
  • tests/unit/lib/cloister/deacon-swarm-verdict-routing.test.ts
  • tests/unit/lib/cloister/review-verdict-feedback.test.ts
  • tests/unit/lib/head-anchor-write-sites.test.ts
💤 Files with no reviewable changes (3)
  • src/lib/cloister/stall-sweeper.ts
  • src/lib/cloister/tests/stall-sweeper.test.ts
  • scripts/circular-deps-baseline.txt
🚧 Files skipped from review as they are similar to previous changes (5)
  • src/lib/pan-dir/records.ts
  • src/lib/tests/review-status-reconcile.test.ts
  • src/lib/overdeck/review-status-record-sync.ts
  • src/lib/cloister/review-agent.ts
  • tests/lib/cloister/review-agent.test.ts

Comment on lines +100 to +112
it('rejects a retired reReviewScope-only POST without persisting it', async () => {
const result = await requestReviewConfig({
method: 'POST',
headers: { 'content-type': 'application/json' },
body: JSON.stringify({ reReviewScope: 'blockers' }),
});

expect(result).toEqual({
status: 400,
body: { error: 'Provide reviewMode and/or reviewModel (null clears the override)' },
});
expect(routeMocks.updateIssueRecord).not.toHaveBeenCalled();
});

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Cover a mixed POST payload.

This test only rejects a body with no supported configuration field. A handler that still reads or persists reReviewScope with reviewMode or reviewModel would pass this test. Add a request with a valid review field and reReviewScope, then assert that persistence and the response omit the retired field.

As per PR objectives, remove the obsolete API field and add coverage for both routes.

🤖 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
`@src/dashboard/server/routes/workspaces/__tests__/review-control-config-route.test.ts`
around lines 100 - 112, The review-control route tests only cover a
retired-field-only POST, not a mixed payload. Extend the relevant POST route
coverage around requestReviewConfig with a valid reviewMode or reviewModel plus
reReviewScope, and assert the retired field is omitted from both the persisted
updateIssueRecord call and the successful response. Add equivalent coverage for
both routes while preserving the existing validation behavior.

Comment on lines +18 to +22
import {
completedPostMerge as _completedPostMerge,
postMergeInFlight as _postMergeInFlight,
resetPostMergeState,
} from './post-merge-state.js';

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🗄️ Data Integrity & Integration | 🟠 Major | 🏗️ Heavy lift

Keep postMergeLifecycle() non-destructive.

As per path instructions, postMergeLifecycle() must preserve the workspace, state, xBRIEF, branches, agents, and sessions. The current implementation still pauses agents, kills work and reviewer sessions, kills post-merge role sessions, and creates a memory reset marker at Lines 471-552. Keep the required Docker teardown, but remove these destructive cleanup steps from the handoff before merging.

Also applies to: 287-287, 716-716

🤖 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 `@src/lib/cloister/merge-agent.ts` around lines 18 - 22, Update
postMergeLifecycle() to make the handoff non-destructive: remove agent pausing,
work/reviewer and post-merge session termination, and memory reset marker
creation while preserving workspace, state, xBRIEF, branches, agents, and
sessions. Retain only the required Docker teardown and ensure the related call
sites and lifecycle flow no longer trigger those destructive cleanup operations.

Source: Path instructions

@eltmon

eltmon commented Aug 5, 2026

Copy link
Copy Markdown
Owner Author

Review CHANGES REQUESTED for PAN-3552

Review Synthesis — PAN-3552 — 2026-08-05T21:17:35Z

Verdict: CHANGES REQUESTED — conflictsSince remains live runtime and durable pipeline state

Context

  • Manifest: /home/eltmon/Projects/overdeck/workspaces/feature-pan-3552/.pan/review/agent-pan-3552-review-11bdaa31/context.json
  • Branch: feature/pan-3552
  • Workspace: /home/eltmon/Projects/overdeck/workspaces/feature-pan-3552
  • PR base: c3cf20667708989489a34a6b3a68ae36f49d2cfc
  • HEAD reviewed: 11bdaa31a582ab559b261f1a90f5a60c9c35a7b1
  • Cycle number: 2
  • Prior cycle SHA: d09c573f9177d5775d56e4bce3844e7bae066636

Convoy Status

Sub-role Signal Output Blocking findings
security ready /home/eltmon/Projects/overdeck/workspaces/feature-pan-3552/.pan/review/agent-pan-3552-review-11bdaa31/security.md 0
correctness ready /home/eltmon/Projects/overdeck/workspaces/feature-pan-3552/.pan/review/agent-pan-3552-review-11bdaa31/correctness.md 0
performance ready /home/eltmon/Projects/overdeck/workspaces/feature-pan-3552/.pan/review/agent-pan-3552-review-11bdaa31/performance.md 0
requirements ready /home/eltmon/Projects/overdeck/workspaces/feature-pan-3552/.pan/review/agent-pan-3552-review-11bdaa31/requirements.md 1

Blocking Findings

[requirements] conflictsSince remains active status and durable-record plumbing — src/lib/review-status-types.ts:56

FR-3/NFR-3 require removal of the retired conflictsSince field and its parked orbit. The branch removes the conflicts parked orbit, but introduces the field as an active optional member of ReviewStatus in the new src/lib/review-status-types.ts, and the existing review-status and durable-record projections continue to hydrate and persist it. The compatibility constraint permits old durable records to carry the extra key, which means readers must ignore it; it does not permit the legacy key to remain live state that is rewritten on unrelated review-status updates.

Remove conflictsSince from the active status and pipeline-record types plus their hydration, serialization, projection, and restoration call sites. Keep the SQLite column physically inert and tolerate legacy JSON records by ignoring the extra key.

Non-blocking Findings

None.

Clean Sub-roles

  • security
  • correctness
  • performance

Source: /home/eltmon/Projects/overdeck/workspaces/feature-pan-3552/.pan/review/agent-pan-3552-review-11bdaa31/synthesis.md

Required action

Fix every blocking review finding, commit the fixes, then re-request review with:

pan review request PAN-3552 -m "Fixed review issues"

Co-Authored-By: Claude <noreply@anthropic.com>
@eltmon

eltmon commented Aug 5, 2026

Copy link
Copy Markdown
Owner Author

Review CHANGES REQUESTED for PAN-3552

Review Synthesis — PAN-3552 — 2026-08-05T22:02:22Z

Verdict: CHANGES REQUESTED — the review-status write door still rewrites the retired conflicts_since column

Context

  • Manifest: /home/eltmon/Projects/overdeck/workspaces/feature-pan-3552/.pan/review/agent-pan-3552-review-92ffee9a/context.json
  • Branch: feature/pan-3552
  • Workspace: /home/eltmon/Projects/overdeck/workspaces/feature-pan-3552
  • PR base: c3cf20667708989489a34a6b3a68ae36f49d2cfc
  • HEAD reviewed: 92ffee9abd3596f8b65a7c4256f4829261ba4900
  • Cycle number: 3
  • Prior cycle SHA: 11bdaa31a582ab559b261f1a90f5a60c9c35a7b1

Convoy Status

Sub-role Signal Output Blocking findings
security ready /home/eltmon/Projects/overdeck/workspaces/feature-pan-3552/.pan/review/agent-pan-3552-review-92ffee9a/security.md 0
correctness ready /home/eltmon/Projects/overdeck/workspaces/feature-pan-3552/.pan/review/agent-pan-3552-review-92ffee9a/correctness.md 0
performance ready /home/eltmon/Projects/overdeck/workspaces/feature-pan-3552/.pan/review/agent-pan-3552-review-92ffee9a/performance.md 0
requirements ready /home/eltmon/Projects/overdeck/workspaces/feature-pan-3552/.pan/review/agent-pan-3552-review-92ffee9a/requirements.md 1

Blocking Findings

[requirements] The review-status write door still serializes conflicts_sincesrc/lib/overdeck/review-status-sync.ts:324

The current-cycle diff removes conflictsSince from the public status type and read mapping, but upsertReviewStatusSync() still includes conflicts_since in its insert and conflict-update column lists and writes null for it on every review-status upsert. FR-3/NFR-3 require this retired field to be absent from active SQLite serialization; the physical column may remain only as inert compatibility storage.

Remove conflicts_since from the SQL insert, value, and update lists while retaining the database schema column. This lets legacy values remain unread and untouched instead of having the write door own and rewrite them.

Non-blocking Findings

[correctness] [demoted: previously reviewed] Anchor-match verdicts omit reviewedAtCommitsrc/lib/cloister/review-verdict-writer.ts:157

The correctness reviewer identified a same-head verdict-anchor issue. src/lib/cloister/review-verdict-writer.ts is in the PR diff, but it did not change since the prior synthesis at 11bdaa31a582ab559b261f1a90f5a60c9c35a7b1, whose reviewers inspected this same branch state. Under the cycle-3 convergence gate, it is not promotable to a blocker in this cycle.

[requirements] [demoted: previously reviewed] Legacy roles.<role>.reReviewScope keys are rejected — src/lib/config-yaml/roles.ts:297

The requirements reviewer identified that the loader rejects an existing retired configuration key rather than ignoring it. That code is in the PR diff but did not change in the current cycle, so the cycle-3 convergence gate keeps it non-blocking here.

[requirements] [demoted: previously reviewed] Stall sweeper retains action-oriented names — src/lib/cloister/stall-sweeper.ts:27

The sweeper's remaining recommendation-budget identifiers are outside the current cycle diff. The cycle-3 convergence gate prevents promoting this newly raised concern to a blocker.

Clean Sub-roles

  • security
  • performance

Source: /home/eltmon/Projects/overdeck/workspaces/feature-pan-3552/.pan/review/agent-pan-3552-review-92ffee9a/synthesis.md

Required action

Fix every blocking review finding, commit the fixes, then re-request review with:

pan review request PAN-3552 -m "Fixed review issues"

1 similar comment
@eltmon

eltmon commented Aug 5, 2026

Copy link
Copy Markdown
Owner Author

Review CHANGES REQUESTED for PAN-3552

Review Synthesis — PAN-3552 — 2026-08-05T22:02:22Z

Verdict: CHANGES REQUESTED — the review-status write door still rewrites the retired conflicts_since column

Context

  • Manifest: /home/eltmon/Projects/overdeck/workspaces/feature-pan-3552/.pan/review/agent-pan-3552-review-92ffee9a/context.json
  • Branch: feature/pan-3552
  • Workspace: /home/eltmon/Projects/overdeck/workspaces/feature-pan-3552
  • PR base: c3cf20667708989489a34a6b3a68ae36f49d2cfc
  • HEAD reviewed: 92ffee9abd3596f8b65a7c4256f4829261ba4900
  • Cycle number: 3
  • Prior cycle SHA: 11bdaa31a582ab559b261f1a90f5a60c9c35a7b1

Convoy Status

Sub-role Signal Output Blocking findings
security ready /home/eltmon/Projects/overdeck/workspaces/feature-pan-3552/.pan/review/agent-pan-3552-review-92ffee9a/security.md 0
correctness ready /home/eltmon/Projects/overdeck/workspaces/feature-pan-3552/.pan/review/agent-pan-3552-review-92ffee9a/correctness.md 0
performance ready /home/eltmon/Projects/overdeck/workspaces/feature-pan-3552/.pan/review/agent-pan-3552-review-92ffee9a/performance.md 0
requirements ready /home/eltmon/Projects/overdeck/workspaces/feature-pan-3552/.pan/review/agent-pan-3552-review-92ffee9a/requirements.md 1

Blocking Findings

[requirements] The review-status write door still serializes conflicts_sincesrc/lib/overdeck/review-status-sync.ts:324

The current-cycle diff removes conflictsSince from the public status type and read mapping, but upsertReviewStatusSync() still includes conflicts_since in its insert and conflict-update column lists and writes null for it on every review-status upsert. FR-3/NFR-3 require this retired field to be absent from active SQLite serialization; the physical column may remain only as inert compatibility storage.

Remove conflicts_since from the SQL insert, value, and update lists while retaining the database schema column. This lets legacy values remain unread and untouched instead of having the write door own and rewrite them.

Non-blocking Findings

[correctness] [demoted: previously reviewed] Anchor-match verdicts omit reviewedAtCommitsrc/lib/cloister/review-verdict-writer.ts:157

The correctness reviewer identified a same-head verdict-anchor issue. src/lib/cloister/review-verdict-writer.ts is in the PR diff, but it did not change since the prior synthesis at 11bdaa31a582ab559b261f1a90f5a60c9c35a7b1, whose reviewers inspected this same branch state. Under the cycle-3 convergence gate, it is not promotable to a blocker in this cycle.

[requirements] [demoted: previously reviewed] Legacy roles.<role>.reReviewScope keys are rejected — src/lib/config-yaml/roles.ts:297

The requirements reviewer identified that the loader rejects an existing retired configuration key rather than ignoring it. That code is in the PR diff but did not change in the current cycle, so the cycle-3 convergence gate keeps it non-blocking here.

[requirements] [demoted: previously reviewed] Stall sweeper retains action-oriented names — src/lib/cloister/stall-sweeper.ts:27

The sweeper's remaining recommendation-budget identifiers are outside the current cycle diff. The cycle-3 convergence gate prevents promoting this newly raised concern to a blocker.

Clean Sub-roles

  • security
  • performance

Source: /home/eltmon/Projects/overdeck/workspaces/feature-pan-3552/.pan/review/agent-pan-3552-review-92ffee9a/synthesis.md

Required action

Fix every blocking review finding, commit the fixes, then re-request review with:

pan review request PAN-3552 -m "Fixed review issues"

Co-Authored-By: Claude <noreply@anthropic.com>

@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: 1

🤖 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 `@tests/unit/lib/pan-1908-no-loss-audit.test.ts`:
- Line 75: Update the review_status column audit in the pan-1908 no-loss test to
include conflicts_since in a dedicated compatibility-only set. Assert 41
physical columns total: 24 durable, 16 ephemeral, and 1 compatibility-only,
while retaining conflicts_since as a physical database column and preserving the
existing classification checks.
🪄 Autofix

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: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 86456d65-377c-4ef9-a45e-d05e9cdca86a

📥 Commits

Reviewing files that changed from the base of the PR and between 11bdaa3 and 9ef214d.

📒 Files selected for processing (21)
  • src/dashboard/frontend/src/components/CommandDeck/ZoneCOverviewTabs/queries.ts
  • src/dashboard/frontend/src/components/IssuePolicyStrip.test.tsx
  • src/dashboard/frontend/src/components/Settings/__tests__/RolesPanel.test.tsx
  • src/dashboard/frontend/src/components/chat/__tests__/composerCommands.no-loss.test.ts
  • src/dashboard/frontend/src/components/chat/__tests__/fixtures/slash-commands.pre-adapter.json
  • src/dashboard/frontend/src/components/chat/__tests__/slashCommands.no-loss.test.ts
  • src/dashboard/server/routes/workspaces/__tests__/review-control-config-route.test.ts
  • src/lib/config-yaml/roles.ts
  • src/lib/overdeck/review-status-record-sync.ts
  • src/lib/overdeck/review-status-sync.ts
  • src/lib/pan-dir/record.ts
  • src/lib/pan-dir/records.ts
  • src/lib/pan-dir/verdict-restore.ts
  • src/lib/parked/__tests__/resolver.test.ts
  • src/lib/review-status-types.ts
  • tests/lib/cloister/review-agent.test.ts
  • tests/unit/lib/cloister/conflict-gate.test.ts
  • tests/unit/lib/head-anchor-write-sites.test.ts
  • tests/unit/lib/overdeck/review-status-sync.test.ts
  • tests/unit/lib/pan-1908-no-loss-audit.test.ts
  • tests/unit/lib/pan-dir/verdict-restore.test.ts
💤 Files with no reviewable changes (11)
  • src/lib/pan-dir/verdict-restore.ts
  • src/dashboard/frontend/src/components/chat/tests/fixtures/slash-commands.pre-adapter.json
  • src/dashboard/frontend/src/components/CommandDeck/ZoneCOverviewTabs/queries.ts
  • src/lib/overdeck/review-status-record-sync.ts
  • tests/unit/lib/cloister/conflict-gate.test.ts
  • src/dashboard/frontend/src/components/IssuePolicyStrip.test.tsx
  • src/lib/parked/tests/resolver.test.ts
  • src/lib/pan-dir/records.ts
  • src/lib/review-status-types.ts
  • src/lib/config-yaml/roles.ts
  • src/lib/pan-dir/record.ts
🚧 Files skipped from review as they are similar to previous changes (2)
  • tests/unit/lib/head-anchor-write-sites.test.ts
  • tests/lib/cloister/review-agent.test.ts


function allReviewStatusColumns(): string[] {
// 41 persisted columns per the PRD (25 durable + 16 ephemeral + 0 delete here).
// 40 persisted columns per the PRD (24 durable + 16 ephemeral + 0 delete here).

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🗄️ Data Integrity & Integration | 🟡 Minor | ⚡ Quick win

Account for the retained compatibility column.

conflicts_since remains in review_status for database compatibility. This audit excludes that column but claims to classify every review_status column. Add a compatibility-only set and assert 41 physical columns: 24 durable, 16 ephemeral, and 1 compatibility-only.

As per PR objectives, retain the physical database column for compatibility.

Also applies to: 154-163

🤖 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 `@tests/unit/lib/pan-1908-no-loss-audit.test.ts` at line 75, Update the
review_status column audit in the pan-1908 no-loss test to include
conflicts_since in a dedicated compatibility-only set. Assert 41 physical
columns total: 24 durable, 16 ephemeral, and 1 compatibility-only, while
retaining conflicts_since as a physical database column and preserving the
existing classification checks.

@eltmon

eltmon commented Aug 5, 2026

Copy link
Copy Markdown
Owner Author

Review CHANGES REQUESTED for PAN-3552

Review Synthesis — PAN-3552 — 2026-08-05T23:08:02.332Z

Verdict: CHANGES REQUESTED — [correctness] Anchor-match verdicts discard the reviewed commit — src/lib/cloister/review-verdict-writer.ts:157

Context

  • Generated by Deacon fallback from completed on-disk reviewer reports.
  • Review directory: /home/eltmon/Projects/overdeck/workspaces/feature-pan-3552/.pan/review/agent-pan-3552-review-9ef214d0

Convoy Status

Sub-role Signal Output Blocking findings
security ready /home/eltmon/Projects/overdeck/workspaces/feature-pan-3552/.pan/review/agent-pan-3552-review-9ef214d0/security.md 0
correctness ready /home/eltmon/Projects/overdeck/workspaces/feature-pan-3552/.pan/review/agent-pan-3552-review-9ef214d0/correctness.md 1
performance ready /home/eltmon/Projects/overdeck/workspaces/feature-pan-3552/.pan/review/agent-pan-3552-review-9ef214d0/performance.md 0
requirements ready /home/eltmon/Projects/overdeck/workspaces/feature-pan-3552/.pan/review/agent-pan-3552-review-9ef214d0/requirements.md 2

Blocking Findings

[correctness] Anchor-match verdicts discard the reviewed commit — src/lib/cloister/review-verdict-writer.ts:157

Source: /home/eltmon/Projects/overdeck/workspaces/feature-pan-3552/.pan/review/agent-pan-3552-review-9ef214d0/correctness.md

[requirements] 1. The sweeper still exposes and persists actor-shaped action state — drop-sweeper-actor-events

Source: /home/eltmon/Projects/overdeck/workspaces/feature-pan-3552/.pan/review/agent-pan-3552-review-9ef214d0/requirements.md

[requirements] 2. A current live review parent prevents verdict-of-record convergence — dispatch-consults-verdict-of-record.ac1

Source: /home/eltmon/Projects/overdeck/workspaces/feature-pan-3552/.pan/review/agent-pan-3552-review-9ef214d0/requirements.md

Non-blocking Findings

See individual reviewer reports.

Clean Sub-roles

  • security
  • performance

Source: /home/eltmon/Projects/overdeck/workspaces/feature-pan-3552/.pan/review/agent-pan-3552-review-9ef214d0/synthesis.md

Required action

Fix every blocking review finding, commit the fixes, then re-request review with:

pan review request PAN-3552 -m "Fixed review issues"

@eltmon

eltmon commented Aug 5, 2026

Copy link
Copy Markdown
Owner Author

Review CHANGES REQUESTED for PAN-3552

Review Synthesis — PAN-3552 — 2026-08-05T23:18:14.259Z

Verdict: CHANGES REQUESTED — [correctness] Anchor-match verdicts discard the reviewed commit — src/lib/cloister/review-verdict-writer.ts:157

Context

  • Generated by Deacon fallback from completed on-disk reviewer reports.
  • Review directory: /home/eltmon/Projects/overdeck/workspaces/feature-pan-3552/.pan/review/agent-pan-3552-review-9ef214d0

Convoy Status

Sub-role Signal Output Blocking findings
security ready /home/eltmon/Projects/overdeck/workspaces/feature-pan-3552/.pan/review/agent-pan-3552-review-9ef214d0/security.md 0
correctness ready /home/eltmon/Projects/overdeck/workspaces/feature-pan-3552/.pan/review/agent-pan-3552-review-9ef214d0/correctness.md 1
performance ready /home/eltmon/Projects/overdeck/workspaces/feature-pan-3552/.pan/review/agent-pan-3552-review-9ef214d0/performance.md 0
requirements ready /home/eltmon/Projects/overdeck/workspaces/feature-pan-3552/.pan/review/agent-pan-3552-review-9ef214d0/requirements.md 2

Blocking Findings

[correctness] Anchor-match verdicts discard the reviewed commit — src/lib/cloister/review-verdict-writer.ts:157

Source: /home/eltmon/Projects/overdeck/workspaces/feature-pan-3552/.pan/review/agent-pan-3552-review-9ef214d0/correctness.md

[requirements] 1. The sweeper still exposes and persists actor-shaped action state — drop-sweeper-actor-events

Source: /home/eltmon/Projects/overdeck/workspaces/feature-pan-3552/.pan/review/agent-pan-3552-review-9ef214d0/requirements.md

[requirements] 2. A current live review parent prevents verdict-of-record convergence — dispatch-consults-verdict-of-record.ac1

Source: /home/eltmon/Projects/overdeck/workspaces/feature-pan-3552/.pan/review/agent-pan-3552-review-9ef214d0/requirements.md

Non-blocking Findings

See individual reviewer reports.

Clean Sub-roles

  • security
  • performance

Source: /home/eltmon/Projects/overdeck/workspaces/feature-pan-3552/.pan/review/agent-pan-3552-review-9ef214d0/synthesis.md

Required action

Fix every blocking review finding, commit the fixes, then re-request review with:

pan review request PAN-3552 -m "Fixed review issues"

Co-Authored-By: Claude <noreply@anthropic.com>
@overdeck-agent
overdeck-agent Bot merged commit 7260c8a into main Aug 5, 2026
11 checks passed
@eltmon
eltmon deleted the feature/pan-3552 branch August 6, 2026 07:30
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