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
+49
View File
@@ -249,6 +249,55 @@ describe("buildPublishPayload — methodSelections", () => {
expect(entry.sections.corePrinciple.length).toBeGreaterThan(0);
});
it("does not seed 75% consensus on a custom decision-making card", () => {
const customId = "00000000-0000-4000-8000-000000000170";
const r = buildPublishPayload({
title: "T",
selectedDecisionApproachIds: [customId],
customMethodCardMetaById: {
[customId]: {
label: "Forum proposals",
supportText: "Anyone can start a thread.",
},
},
decisionApproachDetailsById: {
[customId]: {
corePrinciple: "",
applicableScope: [],
selectedApplicableScope: [],
stepByStepInstructions: "",
consensusLevel: 75,
objectionsDeadlocks: "",
},
},
});
expect(r.ok).toBe(true);
if (!r.ok) return;
const ms = r.document.methodSelections as {
decisionApproaches?: Array<{
supportText?: string;
sections: { consensusLevel?: number };
}>;
};
expect(ms.decisionApproaches?.[0]?.supportText).toBe(
"Anyone can start a thread.",
);
expect(ms.decisionApproaches?.[0]?.sections.consensusLevel).toBeUndefined();
});
it("keeps catalog decision consensus in methodSelections", () => {
const r = buildPublishPayload({
title: "T",
selectedDecisionApproachIds: ["lazy-consensus"],
});
expect(r.ok).toBe(true);
if (!r.ok) return;
const ms = r.document.methodSelections as {
decisionApproaches?: Array<{ sections: { consensusLevel?: number } }>;
};
expect(ms.decisionApproaches?.[0]?.sections.consensusLevel).toBe(100);
});
it("merges override on top of preset for the selected method", () => {
const r = buildPublishPayload({
title: "T",
@@ -3,6 +3,7 @@ import {
buildMethodCardWizardInitialValues,
coreValueDetailsFromWizardFieldBlocks,
facetDetailsToWizardFieldBlocks,
overlayFacetPrefillValues,
} from "../../lib/create/methodCardWizardPrefill";
import type { CustomMethodCardFieldBlock } from "../../lib/create/customMethodCardFieldBlocks";
@@ -219,6 +220,49 @@ describe("facetDetailsToWizardFieldBlocks", () => {
});
});
it("omits a consensus proportion when the draft has no consensus level", () => {
const blocksOut = facetDetailsToWizardFieldBlocks({
group: "decisionApproaches",
draft: {
corePrinciple: "Momentum.",
applicableScope: [],
selectedApplicableScope: [],
stepByStepInstructions: "Post a deadline.",
objectionsDeadlocks: "",
},
headings: {
corePrinciple: "Core Principle",
applicableScope: "Applicable Scope",
stepByStepInstructions: "Step-by-Step Instructions",
consensusLevel: "Consensus Level",
objectionsDeadlocks: "Objections & Deadlocks",
},
});
expect(blocksOut.find((b) => b.kind === "proportion")).toBeUndefined();
});
it("does not inject a seeded 75% proportion onto empty custom drafts", () => {
const next = overlayFacetPrefillValues([], {
group: "decisionApproaches",
draft: {
corePrinciple: "",
applicableScope: [],
selectedApplicableScope: [],
stepByStepInstructions: "",
consensusLevel: 75,
objectionsDeadlocks: "",
},
headings: {
corePrinciple: "Core Principle",
applicableScope: "Applicable Scope",
stepByStepInstructions: "Step-by-Step Instructions",
consensusLevel: "Consensus Level",
objectionsDeadlocks: "Objections & Deadlocks",
},
});
expect(next).toEqual([]);
});
it("maps core value meaning and signals onto text blocks", () => {
expect(
facetDetailsToWizardFieldBlocks({
@@ -314,6 +314,37 @@ describe("createFlowStateFromPublishedRule", () => {
});
});
it("hydrates wizard supportText from published methodSelections", () => {
const customId = "b7c0a9f3-0000-4000-8000-000000000002";
const partial = createFlowStateFromPublishedRule({
id: "rule-custom-desc",
title: "C",
summary: "",
document: {
methodSelections: {
decisionApproaches: [
{
id: customId,
label: "Forum proposals",
supportText: "Anyone can start a thread.",
sections: {
corePrinciple: "",
applicableScope: [],
selectedApplicableScope: [],
stepByStepInstructions: "",
objectionsDeadlocks: "",
},
},
],
},
},
});
expect(partial.customMethodCardMetaById?.[customId]).toEqual({
label: "Forum proposals",
supportText: "Anyone can start a thread.",
});
});
it("sets sections to [] even when methodSelections is missing (edit hydrate)", () => {
const partial = createFlowStateFromPublishedRule({
id: "rule-2",
@@ -248,4 +248,35 @@ describe("parsePublishedDocumentForCommunityRuleDisplay", () => {
},
]);
});
it("shows custom decision description without a seeded 75% consensus row", () => {
const customId = "00000000-0000-4000-8000-000000000170";
const out = parsePublishedDocumentForCommunityRuleDisplay({
sections: [],
methodSelections: {
decisionApproaches: [
{
id: customId,
label: "Forum proposals",
supportText: "Anyone can start a thread.",
sections: {
corePrinciple: "",
applicableScope: [],
selectedApplicableScope: [],
stepByStepInstructions: "",
consensusLevel: 75,
objectionsDeadlocks: "",
},
},
],
},
});
const decision = out.find((s) => s.categoryName === "Decision-making");
expect(decision?.entries).toEqual([
{
title: "Forum proposals",
body: "Anyone can start a thread.",
},
]);
});
});
@@ -0,0 +1,156 @@
import { describe, expect, it } from "vitest";
import {
communityRuleEntryFromMethodChip,
sectionFromDecision,
withoutUnpublishedDecisionConsensus,
} from "../../lib/create/ruleSectionsFromMethodSelections";
const emptyDecisionSections = {
corePrinciple: "",
applicableScope: [] as string[],
selectedApplicableScope: [] as string[],
stepByStepInstructions: "",
consensusLevel: 75,
objectionsDeadlocks: "",
};
describe("withoutUnpublishedDecisionConsensus", () => {
it("keeps catalog consensus when facet copy is present", () => {
const next = withoutUnpublishedDecisionConsensus({
corePrinciple: "Momentum.",
consensusLevel: 100,
});
expect(next.consensusLevel).toBe(100);
});
it("drops seeded consensus on empty custom facet copy", () => {
const next = withoutUnpublishedDecisionConsensus({ ...emptyDecisionSections });
expect(next.consensusLevel).toBeUndefined();
});
it("drops keyed consensus when wizard field blocks exist", () => {
const next = withoutUnpublishedDecisionConsensus(
{ corePrinciple: "Momentum.", consensusLevel: 75 },
[
{
kind: "proportion",
id: "p1",
blockTitle: "Quorum",
defaultPercent: 60,
},
],
);
expect(next.consensusLevel).toBeUndefined();
});
});
describe("communityRuleEntryFromMethodChip", () => {
it("publishes supportText as body when there are no labeled blocks", () => {
expect(
communityRuleEntryFromMethodChip(
"Our process",
{ corePrinciple: "" },
{ corePrinciple: "Core Principle" },
{ supportText: " Members propose in the forum. " },
),
).toEqual({
title: "Our process",
body: "Members propose in the forum.",
});
});
it("keeps supportText alongside wizard blocks", () => {
const entry = communityRuleEntryFromMethodChip(
"Our process",
{ corePrinciple: "" },
{ corePrinciple: "Core Principle" },
{
supportText: "How we decide.",
customFieldBlocks: [
{
kind: "text",
id: "b1",
blockTitle: "Notes",
placeholderText: "Post in #governance.",
},
],
},
);
expect(entry).toEqual({
title: "Our process",
body: "How we decide.",
blocks: [{ label: "Notes", body: "Post in #governance." }],
});
});
});
describe("sectionFromDecision", () => {
it("omits seeded 75% and shows the policy description on a custom card", () => {
const section = sectionFromDecision([
{
id: "00000000-0000-4000-8000-000000000001",
label: "Forum proposals",
supportText: "Anyone can start a thread; silence after a week is consent.",
sections: { ...emptyDecisionSections },
},
]);
expect(section?.categoryName).toBe("Decision-making");
expect(section?.entries).toEqual([
{
title: "Forum proposals",
body: "Anyone can start a thread; silence after a week is consent.",
},
]);
});
it("still emits catalog consensus when facet copy is present", () => {
const section = sectionFromDecision([
{
id: "lazy-consensus",
label: "Lazy Consensus",
sections: {
corePrinciple: "Silence is consent.",
applicableScope: [],
selectedApplicableScope: [],
stepByStepInstructions: "Post a deadline.",
consensusLevel: 100,
objectionsDeadlocks: "Any member can block.",
},
},
]);
const blocks = section?.entries[0]?.blocks ?? [];
expect(blocks).toContainEqual({
label: "Consensus Level",
body: "100%",
});
});
it("does not duplicate consensus when a wizard proportion block exists", () => {
const section = sectionFromDecision(
[
{
id: "00000000-0000-4000-8000-000000000002",
label: "Custom vote",
supportText: "We vote in person.",
sections: {
...emptyDecisionSections,
consensusLevel: 75,
},
},
],
{
"00000000-0000-4000-8000-000000000002": [
{
kind: "proportion",
id: "q",
blockTitle: "Quorum",
defaultPercent: 60,
},
],
},
);
const blocks = section?.entries[0]?.blocks ?? [];
expect(blocks).toEqual([{ label: "Quorum", body: "60%" }]);
expect(section?.entries[0]?.body).toBe("We vote in person.");
});
});