Stop seeding 75% consensus on custom decision cards so wizard copy shows on the published rule.

Wire Back on the final-review chip editor to the same dismiss path as close, instead of a no-op.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
adilallo
2026-08-31 11:28:32 -06:00
co-authored by Cursor
parent 7f67cc6271
commit 511c3efb4c
20 changed files with 531 additions and 36 deletions
+41 -2
View File
@@ -16,7 +16,10 @@ import {
publishedMethodDisplayLabel,
} from "./finalReviewChipPresets";
import { isDocumentEntry } from "./documentEntryGuards";
import { replaceMethodSectionsWithMethodSelections } from "./ruleSectionsFromMethodSelections";
import {
replaceMethodSectionsWithMethodSelections,
withoutUnpublishedDecisionConsensus,
} from "./ruleSectionsFromMethodSelections";
import { templateCategoryToGroupKey } from "./templateReviewMapping";
export { isDocumentEntry } from "./documentEntryGuards";
@@ -78,21 +81,25 @@ export type PublishedMethodSelections = {
id: string;
label: string;
sections: CommunicationMethodDetailEntry;
supportText?: string;
}>;
membership?: Array<{
id: string;
label: string;
sections: MembershipMethodDetailEntry;
supportText?: string;
}>;
decisionApproaches?: Array<{
id: string;
label: string;
sections: DecisionApproachDetailEntry;
supportText?: string;
}>;
conflictManagement?: Array<{
id: string;
label: string;
sections: ConflictManagementDetailEntry;
supportText?: string;
}>;
};
@@ -247,6 +254,14 @@ function pickMethodIds(
return derived;
}
function publishedRowSupportText(
id: string,
meta: CreateFlowState["customMethodCardMetaById"],
): string | undefined {
const t = meta?.[id]?.supportText?.trim();
return t && t.length > 0 ? t : undefined;
}
/**
* Merge `selected*MethodIds` with any saved `{group}MethodDetailsById`
* overrides authored on the final-review screen. Preset defaults from the
@@ -270,6 +285,10 @@ export function buildMethodSelectionsForDocument(
out.communication = commIds.map((id) => {
const preset = communicationPresetFor(id);
const override = state.communicationMethodDetailsById?.[id];
const supportText = publishedRowSupportText(
id,
state.customMethodCardMetaById,
);
return {
id,
label: publishedMethodDisplayLabel(
@@ -278,6 +297,7 @@ export function buildMethodSelectionsForDocument(
state.customMethodCardMetaById,
),
sections: override ? { ...preset, ...override } : preset,
...(supportText ? { supportText } : {}),
};
});
}
@@ -290,6 +310,10 @@ export function buildMethodSelectionsForDocument(
out.membership = memIds.map((id) => {
const preset = membershipPresetFor(id);
const override = state.membershipMethodDetailsById?.[id];
const supportText = publishedRowSupportText(
id,
state.customMethodCardMetaById,
);
return {
id,
label: publishedMethodDisplayLabel(
@@ -298,6 +322,7 @@ export function buildMethodSelectionsForDocument(
state.customMethodCardMetaById,
),
sections: override ? { ...preset, ...override } : preset,
...(supportText ? { supportText } : {}),
};
});
}
@@ -310,6 +335,11 @@ export function buildMethodSelectionsForDocument(
out.decisionApproaches = daIds.map((id) => {
const preset = decisionApproachPresetFor(id);
const override = state.decisionApproachDetailsById?.[id];
const supportText = publishedRowSupportText(
id,
state.customMethodCardMetaById,
);
const merged = override ? { ...preset, ...override } : preset;
return {
id,
label: publishedMethodDisplayLabel(
@@ -317,7 +347,11 @@ export function buildMethodSelectionsForDocument(
id,
state.customMethodCardMetaById,
),
sections: override ? { ...preset, ...override } : preset,
sections: withoutUnpublishedDecisionConsensus(
{ ...merged },
state.customMethodCardFieldBlocksById?.[id],
) as DecisionApproachDetailEntry,
...(supportText ? { supportText } : {}),
};
});
}
@@ -330,6 +364,10 @@ export function buildMethodSelectionsForDocument(
out.conflictManagement = cmIds.map((id) => {
const preset = conflictManagementPresetFor(id);
const override = state.conflictManagementDetailsById?.[id];
const supportText = publishedRowSupportText(
id,
state.customMethodCardMetaById,
);
return {
id,
label: publishedMethodDisplayLabel(
@@ -338,6 +376,7 @@ export function buildMethodSelectionsForDocument(
state.customMethodCardMetaById,
),
sections: override ? { ...preset, ...override } : preset,
...(supportText ? { supportText } : {}),
};
});
}
+9 -6
View File
@@ -106,7 +106,7 @@ export function membershipPresetFor(id: string): MembershipMethodDetailEntry {
};
}
/** Default consensus level used when presets omit a value (see DecisionApproachesScreen). */
/** Default consensus level used when a **catalog** preset omits a value. */
export const DECISION_CONSENSUS_LEVEL_DEFAULT = 75;
export function decisionApproachPresetFor(
@@ -114,19 +114,22 @@ export function decisionApproachPresetFor(
): DecisionApproachDetailEntry {
const method = findMethod(decisionApproachesMessages, id);
const s = method?.sections ?? {};
return {
const entry: DecisionApproachDetailEntry = {
corePrinciple: asString(s.corePrinciple),
applicableScope: asStringArray(s.applicableScope),
selectedApplicableScope: [],
stepByStepInstructions: asString(s.stepByStepInstructions),
consensusLevel: asNumberClamped(
objectionsDeadlocks: asString(s.objectionsDeadlocks),
};
if (method) {
entry.consensusLevel = asNumberClamped(
s.consensusLevel,
0,
100,
DECISION_CONSENSUS_LEVEL_DEFAULT,
),
objectionsDeadlocks: asString(s.objectionsDeadlocks),
};
);
}
return entry;
}
export function conflictManagementPresetFor(
+9 -2
View File
@@ -195,12 +195,19 @@ function mapFacetPrefillToWizardFieldBlocks(
prefill.headings.stepByStepInstructions,
prefill.draft.stepByStepInstructions,
),
{
);
if (
typeof prefill.draft.consensusLevel === "number" &&
facetPrefillHasContent(prefill)
) {
blocks.push({
kind: "proportion",
id: "facet-consensusLevel",
blockTitle: prefill.headings.consensusLevel,
defaultPercent: clampPercent(prefill.draft.consensusLevel),
},
});
}
blocks.push(
textBlock(
"facet-objectionsDeadlocks",
prefill.headings.objectionsDeadlocks,
@@ -22,6 +22,7 @@ function customMethodCardMetaFromPublishedSelections(
| Array<{
id: string;
label: string;
supportText?: string;
}>
| undefined,
) => {
@@ -32,7 +33,9 @@ function customMethodCardMetaFromPublishedSelections(
if (methodLabelFor(groupKey, id).length > 0) continue;
const label = typeof row.label === "string" ? row.label.trim() : "";
if (!label) continue;
meta[id] = { label, supportText: "" };
const supportText =
typeof row.supportText === "string" ? row.supportText : "";
meta[id] = { label, supportText };
}
};
absorb("communication", ms.communication);
+76 -6
View File
@@ -78,6 +78,8 @@ export function labeledBlocksFromCustomMethodCardFieldBlocks(
export type CommunityRuleEntryFromChipOptions = {
consensusLevelKey?: string;
customFieldBlocks?: CustomMethodCardFieldBlock[];
/** Wizard step-2 policy description (`customMethodCardMetaById.supportText`). */
supportText?: string;
};
/** Canonical `categoryName` strings for method groups in published documents. */
@@ -195,8 +197,64 @@ export function communityRuleEntryFromMethodChip(
? labeledBlocksFromCustomMethodCardFieldBlocks(options.customFieldBlocks)
: [];
const blocks = [...presetBlocks, ...wizardBlocks];
if (blocks.length === 0) return null;
return { title, body: "", blocks };
const description = nonEmptyTrimmed(options?.supportText);
if (blocks.length === 0) {
if (!description) return null;
return { title, body: description };
}
return {
title,
body: description ?? "",
blocks,
};
}
function decisionApproachHasPublishableFacetCopy(
sections: Record<string, unknown>,
): boolean {
return Boolean(
nonEmptyTrimmed(sections.corePrinciple) ||
nonEmptyTrimmed(sections.stepByStepInstructions) ||
nonEmptyTrimmed(sections.objectionsDeadlocks) ||
formatScopePayload(sections.applicableScope) ||
formatScopePayload(sections.selectedApplicableScope),
);
}
/**
* Catalog methods publish their consensus figure. User-authored custom cards
* often seed `75` with empty facet copy — skip that unless the author actually
* filled decision sections. Wizard field blocks (including proportion) are the
* source of truth when present.
*/
function shouldPublishDecisionConsensusLevel(
sections: Record<string, unknown>,
customFieldBlocks?: CustomMethodCardFieldBlock[],
): boolean {
if (
typeof sections.consensusLevel !== "number" ||
Number.isNaN(sections.consensusLevel)
) {
return false;
}
if (customFieldBlocks && customFieldBlocks.length > 0) {
return false;
}
return decisionApproachHasPublishableFacetCopy(sections);
}
/** Drop seeded / wizard-superseded `consensusLevel` before publish or hydrate. */
export function withoutUnpublishedDecisionConsensus(
sections: Record<string, unknown>,
customFieldBlocks?: CustomMethodCardFieldBlock[],
): Record<string, unknown> {
if (shouldPublishDecisionConsensusLevel(sections, customFieldBlocks)) {
return sections;
}
if (!("consensusLevel" in sections)) return sections;
const next = { ...sections };
delete next.consensusLevel;
return next;
}
export function sectionFromCommunication(
@@ -209,6 +267,7 @@ export function sectionFromCommunication(
const sec = m.sections as unknown as Record<string, unknown>;
const e = communityRuleEntryFromMethodChip(m.label, sec, COMM_LABELS, {
customFieldBlocks: customFieldBlocksById?.[m.id],
supportText: m.supportText,
});
if (e) entries.push(e);
}
@@ -227,6 +286,7 @@ export function sectionFromMembership(
const sec = m.sections as unknown as Record<string, unknown>;
const e = communityRuleEntryFromMethodChip(m.label, sec, MEM_LABELS, {
customFieldBlocks: customFieldBlocksById?.[m.id],
supportText: m.supportText,
});
if (e) entries.push(e);
}
@@ -254,10 +314,19 @@ export function sectionFromDecision(
);
if (scope) merged.applicableScope = scope;
delete merged.selectedApplicableScope;
const e = communityRuleEntryFromMethodChip(m.label, merged, DEC_LABELS, {
consensusLevelKey: "consensusLevel",
customFieldBlocks: customFieldBlocksById?.[m.id],
});
const e = communityRuleEntryFromMethodChip(
m.label,
withoutUnpublishedDecisionConsensus(
merged,
customFieldBlocksById?.[m.id],
),
DEC_LABELS,
{
consensusLevelKey: "consensusLevel",
customFieldBlocks: customFieldBlocksById?.[m.id],
supportText: m.supportText,
},
);
if (e) entries.push(e);
}
return entries.length > 0
@@ -281,6 +350,7 @@ export function sectionFromConflict(
delete merged.selectedApplicableScope;
const e = communityRuleEntryFromMethodChip(m.label, merged, CM_LABELS, {
customFieldBlocks: customFieldBlocksById?.[m.id],
supportText: m.supportText,
});
if (e) entries.push(e);
}
+1 -1
View File
@@ -54,7 +54,7 @@ const decisionApproachDetailEntrySchema = z.object({
applicableScope: z.array(z.string().max(2000)).max(50),
selectedApplicableScope: z.array(z.string().max(2000)).max(50),
stepByStepInstructions: z.string().max(8000),
consensusLevel: z.number().int().min(0).max(100),
consensusLevel: z.number().int().min(0).max(100).optional(),
objectionsDeadlocks: z.string().max(8000),
});