diff --git a/src/app/(app)/projects/[projectId]/deliverables/[deliverableId]/page.tsx b/src/app/(app)/projects/[projectId]/deliverables/[deliverableId]/page.tsx
index bf4896a..6b71a74 100644
--- a/src/app/(app)/projects/[projectId]/deliverables/[deliverableId]/page.tsx
+++ b/src/app/(app)/projects/[projectId]/deliverables/[deliverableId]/page.tsx
@@ -351,7 +351,34 @@ export default function DeliverableDetailPage() {
{stages.map((stage: any) => {
- const available = TRANSITIONS[stage.status] ?? [];
+ // Per-stage approval type drives both the inline transition
+ // set AND whether the StageReviewPanel below the row owns
+ // the action buttons. NONE = open/close only (Start Work,
+ // Mark Complete, Reopen — nothing else). SIMPLE/FORMAL hand
+ // off to the review panel.
+ const stageApprovalType =
+ stage.stageDefinition?.approvalType ??
+ stage.template?.approvalType ??
+ "NONE";
+ const isNoneApproval = stageApprovalType === "NONE";
+
+ // For NONE stages, override the transition set with a minimal
+ // open/close shape so producers never see Submit-for-Review,
+ // Approve, Request-Changes, Mark-Delivered on a non-review row.
+ const NONE_TRANSITIONS: Record = {
+ BLOCKED: [],
+ NOT_STARTED: ["IN_PROGRESS"],
+ IN_PROGRESS: ["APPROVED"],
+ IN_REVIEW: ["APPROVED"],
+ CHANGES_REQUESTED: ["IN_PROGRESS"],
+ APPROVED: ["IN_PROGRESS"],
+ DELIVERED: ["IN_PROGRESS"],
+ SKIPPED: ["NOT_STARTED"],
+ };
+ const available = isNoneApproval
+ ? NONE_TRANSITIONS[stage.status] ?? []
+ : TRANSITIONS[stage.status] ?? [];
+
const assignments = stage.assignments ?? [];
const isGate = stage.stageDefinition?.isCriticalGate ?? stage.template.isCriticalGate;
const isOptional = stage.stageDefinition?.isOptional ?? stage.template.isOptional;
@@ -474,9 +501,15 @@ export default function DeliverableDetailPage() {
stage.status === "DELIVERED")) ||
(nextStatus === "NOT_STARTED" &&
stage.status === "SKIPPED");
+ // NONE-approval stages don't have the review
+ // concept — relabel APPROVED to "Mark Complete"
+ // so the affordance reads as a workflow close,
+ // not a review approval.
const label = isReopen
? "Reopen"
- : (TRANSITION_LABELS[nextStatus] ?? nextStatus);
+ : isNoneApproval && nextStatus === "APPROVED"
+ ? "Mark Complete"
+ : (TRANSITION_LABELS[nextStatus] ?? nextStatus);
return (