fix(gate): empty memory phase shows a notice and auto-advances instead of an empty checklist
This commit is contained in:
@@ -0,0 +1,16 @@
|
|||||||
|
const test = require("node:test");
|
||||||
|
const assert = require("node:assert");
|
||||||
|
const { shouldSkipEmptyDecide } = require("../../tht-gate.js");
|
||||||
|
|
||||||
|
test("skips the widget only when empty AND allow_empty AND advance", () => {
|
||||||
|
assert.equal(shouldSkipEmptyDecide({ meritCount: 0, allowEmpty: true, advance: true }), true);
|
||||||
|
});
|
||||||
|
|
||||||
|
test("does not skip when there are merito options", () => {
|
||||||
|
assert.equal(shouldSkipEmptyDecide({ meritCount: 2, allowEmpty: true, advance: true }), false);
|
||||||
|
});
|
||||||
|
|
||||||
|
test("does not skip when allow_empty is false or advance is false", () => {
|
||||||
|
assert.equal(shouldSkipEmptyDecide({ meritCount: 0, allowEmpty: false, advance: true }), false);
|
||||||
|
assert.equal(shouldSkipEmptyDecide({ meritCount: 0, allowEmpty: true, advance: false }), false);
|
||||||
|
});
|
||||||
@@ -267,6 +267,13 @@ export function resolveConfirmOutcome(resp) {
|
|||||||
return { kind: "unknown", choice };
|
return { kind: "unknown", choice };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// True when a reviewer_decide has no merito options but is allowed to close empty
|
||||||
|
// and advance (the empty memory phase F2). The gate then shows an info notice and
|
||||||
|
// auto-advances instead of presenting an empty checklist.
|
||||||
|
export function shouldSkipEmptyDecide({ meritCount, allowEmpty, advance }) {
|
||||||
|
return meritCount === 0 && !!allowEmpty && !!advance;
|
||||||
|
}
|
||||||
|
|
||||||
export async function emitAndWait(ctx, descriptor) {
|
export async function emitAndWait(ctx, descriptor) {
|
||||||
for (;;) {
|
for (;;) {
|
||||||
const value = await ctx.ui.input(JSON.stringify(descriptor), "");
|
const value = await ctx.ui.input(JSON.stringify(descriptor), "");
|
||||||
@@ -524,14 +531,25 @@ export default function (pi) {
|
|||||||
const { session, title, options: opts, advance } = params;
|
const { session, title, options: opts, advance } = params;
|
||||||
const phase = phaseId(ctx, currentPhase(ctx, session));
|
const phase = phaseId(ctx, currentPhase(ctx, session));
|
||||||
const toAdd = [];
|
const toAdd = [];
|
||||||
|
const meritOptions = opts
|
||||||
|
.filter((o) => !isReserved(o.label))
|
||||||
|
.map((o) => ({ id: o.id, label: o.label }));
|
||||||
|
if (shouldSkipEmptyDecide({ meritCount: meritOptions.length, allowEmpty: params.allow_empty ?? false, advance })) {
|
||||||
|
await ctx.ui.notify(
|
||||||
|
"Nessuna memory riutilizzabile per questa domanda — passo alla fase successiva.",
|
||||||
|
"info",
|
||||||
|
);
|
||||||
|
advanceIfReady(ctx, session);
|
||||||
|
return textResult(
|
||||||
|
"Fase memoria vuota: nessuna decisione da registrare, avanzamento automatico alla fase successiva.",
|
||||||
|
);
|
||||||
|
}
|
||||||
const widget = buildMultiselectRequest({
|
const widget = buildMultiselectRequest({
|
||||||
id: `u${Date.now()}`,
|
id: `u${Date.now()}`,
|
||||||
phase,
|
phase,
|
||||||
title,
|
title,
|
||||||
allowEmpty: params.allow_empty ?? false,
|
allowEmpty: params.allow_empty ?? false,
|
||||||
options: opts
|
options: meritOptions,
|
||||||
.filter((o) => !isReserved(o.label))
|
|
||||||
.map((o) => ({ id: o.id, label: o.label })),
|
|
||||||
recommended: opts.find((o) => o.recommended)?.id ?? null,
|
recommended: opts.find((o) => o.recommended)?.id ?? null,
|
||||||
});
|
});
|
||||||
const resp = await emitAndWait(ctx, widget);
|
const resp = await emitAndWait(ctx, widget);
|
||||||
|
|||||||
Reference in New Issue
Block a user