@wrongstack/tools 0.295.0 → 0.295.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/auto-proceed-loop-guard.d.ts +31 -0
- package/dist/auto-proceed-loop-guard.d.ts.map +1 -1
- package/dist/auto-proceed-loop-guard.js +24 -1
- package/dist/auto-proceed-loop-guard.js.map +2 -2
- package/dist/bash.js +39 -23
- package/dist/bash.js.map +2 -2
- package/dist/builtin.js +278 -109
- package/dist/builtin.js.map +4 -4
- package/dist/codebase-index/generic-parser.d.ts.map +1 -1
- package/dist/codebase-index/index.js +48 -47
- package/dist/codebase-index/index.js.map +2 -2
- package/dist/codebase-index/indexer.d.ts.map +1 -1
- package/dist/codebase-index/worker.js +48 -47
- package/dist/codebase-index/worker.js.map +2 -2
- package/dist/codebase-index/writer.d.ts.map +1 -1
- package/dist/exec.js +39 -23
- package/dist/exec.js.map +2 -2
- package/dist/glob.d.ts.map +1 -1
- package/dist/glob.js +80 -30
- package/dist/glob.js.map +4 -4
- package/dist/grep.d.ts.map +1 -1
- package/dist/grep.js +87 -20
- package/dist/grep.js.map +4 -4
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +281 -109
- package/dist/index.js.map +4 -4
- package/dist/kanban-evidence-bridge.d.ts +21 -0
- package/dist/kanban-evidence-bridge.d.ts.map +1 -0
- package/dist/kanban.d.ts +17 -1
- package/dist/kanban.d.ts.map +1 -1
- package/dist/kanban.js +164 -7
- package/dist/kanban.js.map +3 -3
- package/dist/pack.js +278 -109
- package/dist/pack.js.map +4 -4
- package/dist/process-registry-persistent.d.ts.map +1 -1
- package/dist/ps-slash.js +39 -23
- package/dist/ps-slash.js.map +2 -2
- package/dist/tool-tier.js +278 -109
- package/dist/tool-tier.js.map +4 -4
- package/dist/tree.d.ts.map +1 -1
- package/dist/tree.js +2 -14
- package/dist/tree.js.map +2 -2
- package/dist/win32.d.ts +10 -0
- package/dist/win32.d.ts.map +1 -0
- package/dist/win32.js +67 -0
- package/dist/win32.js.map +7 -0
- package/package.json +7 -3
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Kanban → completed-work ledger bridge.
|
|
3
|
+
*
|
|
4
|
+
* Links the two evidence systems: when a task's verification report is
|
|
5
|
+
* produced (verify_completion, the completion gate via mark_assignment, or a
|
|
6
|
+
* managed Done transition), the session's completed-work ledger gets an entry
|
|
7
|
+
* pointing back at the report. The kanban package cannot do this itself — it
|
|
8
|
+
* has zero core dependency — so the bridge lives here in tools, which owns
|
|
9
|
+
* both sides.
|
|
10
|
+
*
|
|
11
|
+
* Best-effort by contract: a ledger failure must never turn a successful
|
|
12
|
+
* board mutation into an apparent task failure.
|
|
13
|
+
*/
|
|
14
|
+
import type { Context } from '@wrongstack/core/agent';
|
|
15
|
+
import type { KanbanVerificationReport } from '@wrongstack/kanban';
|
|
16
|
+
/** Stable dedupe key — re-verifying the same task updates the entry in place. */
|
|
17
|
+
export declare function kanbanEvidenceKey(boardId: string, taskId: string): string;
|
|
18
|
+
/** Parseable deep-link pointer to the persisted report. */
|
|
19
|
+
export declare function kanbanEvidencePointer(boardId: string, taskId: string): string;
|
|
20
|
+
export declare function recordKanbanVerificationEvidence(ctx: Context, report: KanbanVerificationReport): void;
|
|
21
|
+
//# sourceMappingURL=kanban-evidence-bridge.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"kanban-evidence-bridge.d.ts","sourceRoot":"","sources":["../src/kanban-evidence-bridge.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,wBAAwB,CAAC;AAEtD,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,oBAAoB,CAAC;AAEnE,iFAAiF;AACjF,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,CAEzE;AAED,2DAA2D;AAC3D,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,CAE7E;AAED,wBAAgB,gCAAgC,CAC9C,GAAG,EAAE,OAAO,EACZ,MAAM,EAAE,wBAAwB,GAC/B,IAAI,CAcN"}
|
package/dist/kanban.d.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import type { SerializedTaskGraph, Tool } from '@wrongstack/core/types';
|
|
2
2
|
import type { AssignKanbanTaskInput, KanbanAgentRunStatus, KanbanBoard, KanbanBoardSummary, KanbanEvent, KanbanLifecycleStage, KanbanOrchestrationSnapshot, KanbanQueueHealth, KanbanSearchResult, KanbanTask, KanbanTaskPriority, KanbanTaskStatus, KanbanTaskType, KanbanVerificationReport } from '@wrongstack/kanban';
|
|
3
|
-
type
|
|
3
|
+
import type { KanbanCompletionGateEnforcement, KanbanDecompositionSubtask } from '@wrongstack/kanban';
|
|
4
|
+
type KanbanAction = 'list_boards' | 'get_board' | 'create_board' | 'duplicate_board' | 'update_board' | 'delete_board' | 'generate_board' | 'export_markdown' | 'export_task_graph' | 'sync_task_graph' | 'create_from_graph' | 'import_session_tasks' | 'search_tasks' | 'ready_tasks' | 'snapshot' | 'add_column' | 'update_column' | 'delete_column' | 'add_task' | 'split_task' | 'merge_tasks' | 'copy_task' | 'transfer_task' | 'get_task' | 'update_task' | 'transition_task' | 'move_task' | 'delete_task' | 'set_chain' | 'get_chain' | 'claim_task' | 'release_task' | 'assign_task' | 'mark_assignment' | 'heartbeat_assignment' | 'recover_stale' | 'events' | 'queue_health' | 'add_dependency' | 'add_goal_metric' | 'update_goal_metric' | 'add_check' | 'update_check' | 'add_note' | 'add_link' | 'verify_completion' | 'split_atomic' | 'assess_atomicity' | 'propose_decomposition';
|
|
4
5
|
interface KanbanToolInput extends Omit<AssignKanbanTaskInput, 'status'> {
|
|
5
6
|
action: KanbanAction;
|
|
6
7
|
boardId?: string | undefined;
|
|
@@ -109,10 +110,25 @@ interface KanbanToolInput extends Omit<AssignKanbanTaskInput, 'status'> {
|
|
|
109
110
|
estimatedHours?: number | undefined;
|
|
110
111
|
/** Actual effort in hours for add_task/update_task. */
|
|
111
112
|
actualHours?: number | undefined;
|
|
113
|
+
/** create_board/update_board: atomicity policy mode. */
|
|
114
|
+
atomicityMode?: 'off' | 'assess' | 'enforce' | undefined;
|
|
115
|
+
/** create_board/update_board: how proposed decompositions are applied. */
|
|
116
|
+
atomicityDecomposition?: 'auto' | 'propose' | undefined;
|
|
117
|
+
/** create_board/update_board: completion-gate enforcement. */
|
|
118
|
+
gateEnforcement?: KanbanCompletionGateEnforcement | undefined;
|
|
119
|
+
/** propose_decomposition: 2+ proposed subtasks. */
|
|
120
|
+
subtasks?: KanbanDecompositionSubtask[] | undefined;
|
|
112
121
|
}
|
|
113
122
|
interface KanbanToolOutput {
|
|
114
123
|
ok: boolean;
|
|
115
124
|
verdict?: KanbanVerificationReport['verdict'] | undefined;
|
|
125
|
+
/** Completion-gate outcome when a completion path ran the universal gate. */
|
|
126
|
+
gate?: {
|
|
127
|
+
enforcement: KanbanCompletionGateEnforcement;
|
|
128
|
+
allowed: boolean;
|
|
129
|
+
verdict: KanbanVerificationReport['verdict'] | 'skipped';
|
|
130
|
+
issues: string[];
|
|
131
|
+
} | undefined;
|
|
116
132
|
message: string;
|
|
117
133
|
board?: KanbanBoard | undefined;
|
|
118
134
|
boards?: KanbanBoardSummary[] | undefined;
|
package/dist/kanban.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"kanban.d.ts","sourceRoot":"","sources":["../src/kanban.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAyB,mBAAmB,EAAE,IAAI,EAAE,MAAM,wBAAwB,CAAC;AAE/F,OAAO,KAAK,EACV,qBAAqB,EAErB,oBAAoB,EACpB,WAAW,EACX,kBAAkB,EAClB,WAAW,EACX,oBAAoB,EACpB,2BAA2B,EAC3B,iBAAiB,EACjB,kBAAkB,EAClB,UAAU,EACV,kBAAkB,EAClB,gBAAgB,EAChB,cAAc,EACd,wBAAwB,EACzB,MAAM,oBAAoB,CAAC;
|
|
1
|
+
{"version":3,"file":"kanban.d.ts","sourceRoot":"","sources":["../src/kanban.ts"],"names":[],"mappings":"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"}
|
package/dist/kanban.js
CHANGED
|
@@ -49,9 +49,35 @@ import {
|
|
|
49
49
|
updateGoalMetricOnTask,
|
|
50
50
|
updateTask,
|
|
51
51
|
updateTaskAssignment,
|
|
52
|
-
verifyTaskCompletion
|
|
52
|
+
verifyTaskCompletion,
|
|
53
|
+
finalizeTaskCompletion,
|
|
54
|
+
assessTaskAtomicity,
|
|
55
|
+
proposeTaskDecomposition
|
|
53
56
|
} from "@wrongstack/kanban";
|
|
54
57
|
|
|
58
|
+
// src/kanban-evidence-bridge.ts
|
|
59
|
+
import { recordCompletedWorkEvidence } from "@wrongstack/core/utils";
|
|
60
|
+
function kanbanEvidenceKey(boardId, taskId) {
|
|
61
|
+
return `kanban:${boardId}:${taskId}`;
|
|
62
|
+
}
|
|
63
|
+
function kanbanEvidencePointer(boardId, taskId) {
|
|
64
|
+
return `kanban://${boardId}/${taskId}#verificationReport`;
|
|
65
|
+
}
|
|
66
|
+
function recordKanbanVerificationEvidence(ctx, report) {
|
|
67
|
+
try {
|
|
68
|
+
const passed = report.checks.filter((check) => check.status === "passed").length;
|
|
69
|
+
const completedAt = Date.parse(report.completedAt);
|
|
70
|
+
recordCompletedWorkEvidence(ctx, {
|
|
71
|
+
key: kanbanEvidenceKey(report.boardId, report.taskId),
|
|
72
|
+
source: "verification",
|
|
73
|
+
summary: `${report.taskTitle} \u2014 verification ${report.verdict} (${passed}/${report.checks.length} checks)`,
|
|
74
|
+
...Number.isFinite(completedAt) ? { completedAt } : {},
|
|
75
|
+
evidence: kanbanEvidencePointer(report.boardId, report.taskId)
|
|
76
|
+
});
|
|
77
|
+
} catch {
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
|
|
55
81
|
// src/session-kanban.ts
|
|
56
82
|
import { GlobalMailbox } from "@wrongstack/core/coordination";
|
|
57
83
|
import {
|
|
@@ -172,7 +198,9 @@ var kanbanTool = {
|
|
|
172
198
|
"add_note",
|
|
173
199
|
"add_link",
|
|
174
200
|
"verify_completion",
|
|
175
|
-
"split_atomic"
|
|
201
|
+
"split_atomic",
|
|
202
|
+
"assess_atomicity",
|
|
203
|
+
"propose_decomposition"
|
|
176
204
|
]
|
|
177
205
|
},
|
|
178
206
|
boardId: { type: "string" },
|
|
@@ -308,7 +336,24 @@ var kanbanTool = {
|
|
|
308
336
|
includeCompletedTasks: { type: "boolean" },
|
|
309
337
|
preserveAssignment: { type: "boolean" },
|
|
310
338
|
preserveDependencies: { type: "boolean" },
|
|
311
|
-
moveTasksToColumnId: { type: "string" }
|
|
339
|
+
moveTasksToColumnId: { type: "string" },
|
|
340
|
+
atomicityMode: { type: "string", enum: ["off", "assess", "enforce"] },
|
|
341
|
+
atomicityDecomposition: { type: "string", enum: ["auto", "propose"] },
|
|
342
|
+
gateEnforcement: { type: "string", enum: ["strict", "soft", "off"] },
|
|
343
|
+
subtasks: {
|
|
344
|
+
type: "array",
|
|
345
|
+
minItems: 2,
|
|
346
|
+
items: {
|
|
347
|
+
type: "object",
|
|
348
|
+
properties: {
|
|
349
|
+
title: { type: "string" },
|
|
350
|
+
description: { type: "string" },
|
|
351
|
+
successCriteria: { type: "array", items: { type: "string" } },
|
|
352
|
+
dependsOnIndex: { type: "array", items: { type: "number" } }
|
|
353
|
+
},
|
|
354
|
+
required: ["title"]
|
|
355
|
+
}
|
|
356
|
+
}
|
|
312
357
|
},
|
|
313
358
|
required: ["action"]
|
|
314
359
|
},
|
|
@@ -348,7 +393,14 @@ var kanbanTool = {
|
|
|
348
393
|
title: input.title,
|
|
349
394
|
...input.description !== void 0 ? { description: input.description } : {},
|
|
350
395
|
...input.tags !== void 0 ? { tags: input.tags } : {},
|
|
351
|
-
...input.generatedBy !== void 0 ? { generatedBy: input.generatedBy } : {}
|
|
396
|
+
...input.generatedBy !== void 0 ? { generatedBy: input.generatedBy } : {},
|
|
397
|
+
...input.atomicityMode !== void 0 ? {
|
|
398
|
+
atomicity: {
|
|
399
|
+
mode: input.atomicityMode,
|
|
400
|
+
decomposition: input.atomicityDecomposition ?? "propose"
|
|
401
|
+
}
|
|
402
|
+
} : {},
|
|
403
|
+
...input.gateEnforcement !== void 0 ? { completionGate: { enforcement: input.gateEnforcement } } : {}
|
|
352
404
|
});
|
|
353
405
|
return { ok: true, message: `Board created: ${board.title}`, board };
|
|
354
406
|
}
|
|
@@ -357,7 +409,14 @@ var kanbanTool = {
|
|
|
357
409
|
const board = await updateBoard2(projectRoot, input.boardId, {
|
|
358
410
|
...input.title !== void 0 ? { title: input.title } : {},
|
|
359
411
|
...input.description !== void 0 ? { description: input.description } : {},
|
|
360
|
-
...input.tags !== void 0 ? { tags: input.tags } : {}
|
|
412
|
+
...input.tags !== void 0 ? { tags: input.tags } : {},
|
|
413
|
+
...input.atomicityMode !== void 0 ? {
|
|
414
|
+
atomicity: {
|
|
415
|
+
mode: input.atomicityMode,
|
|
416
|
+
decomposition: input.atomicityDecomposition ?? "propose"
|
|
417
|
+
}
|
|
418
|
+
} : {},
|
|
419
|
+
...input.gateEnforcement !== void 0 ? { completionGate: { enforcement: input.gateEnforcement } } : {}
|
|
361
420
|
});
|
|
362
421
|
return board ? okBoard(board, "Board updated.") : fail("Board not found.");
|
|
363
422
|
}
|
|
@@ -565,7 +624,12 @@ var kanbanTool = {
|
|
|
565
624
|
case "add_task": {
|
|
566
625
|
if (!input.boardId || !input.title) return fail("add_task requires boardId and title.");
|
|
567
626
|
const result2 = await addTask(projectRoot, input.boardId, taskInput(input));
|
|
568
|
-
|
|
627
|
+
if (!result2) return fail("Board not found.");
|
|
628
|
+
return okTask(
|
|
629
|
+
result2.board,
|
|
630
|
+
result2.task,
|
|
631
|
+
`Task added.${atomicityNudge(result2.task)}`
|
|
632
|
+
);
|
|
569
633
|
}
|
|
570
634
|
case "split_task": {
|
|
571
635
|
if (!input.boardId || !input.taskId || !input.childTitles?.length) {
|
|
@@ -645,6 +709,19 @@ var kanbanTool = {
|
|
|
645
709
|
"transition_task requires boardId, taskId, lifecycleStage, author, and transitionComment."
|
|
646
710
|
);
|
|
647
711
|
}
|
|
712
|
+
if (input.lifecycleStage === "done") {
|
|
713
|
+
const boardBefore = await getBoard2(projectRoot, input.boardId);
|
|
714
|
+
const taskBefore = boardBefore ? await getTask(projectRoot, input.boardId, input.taskId) : null;
|
|
715
|
+
if (boardBefore && taskBefore && !taskBefore.verificationReport && (taskBefore.atomic || Boolean(taskBefore.successCriteria?.length))) {
|
|
716
|
+
const preGate = await verifyTaskCompletion(projectRoot, input.boardId, taskBefore.id, {
|
|
717
|
+
persist: false
|
|
718
|
+
});
|
|
719
|
+
await updateTask(projectRoot, input.boardId, taskBefore.id, {
|
|
720
|
+
verificationReport: preGate.report,
|
|
721
|
+
successCriteria: preGate.task.successCriteria
|
|
722
|
+
});
|
|
723
|
+
}
|
|
724
|
+
}
|
|
648
725
|
const result2 = await transitionTask(projectRoot, input.boardId, input.taskId, {
|
|
649
726
|
to: input.lifecycleStage,
|
|
650
727
|
actor: input.author,
|
|
@@ -659,6 +736,9 @@ var kanbanTool = {
|
|
|
659
736
|
} : {},
|
|
660
737
|
patch: taskPatch(input)
|
|
661
738
|
});
|
|
739
|
+
if (result2 && input.lifecycleStage === "done" && result2.task.verificationReport) {
|
|
740
|
+
recordKanbanVerificationEvidence(ctx, result2.task.verificationReport);
|
|
741
|
+
}
|
|
662
742
|
return result2 ? okTask(result2.board, result2.task, `Task advanced to ${result2.transition.to}.`) : fail("Board or task not found.");
|
|
663
743
|
}
|
|
664
744
|
case "move_task": {
|
|
@@ -772,7 +852,31 @@ var kanbanTool = {
|
|
|
772
852
|
// is atomic inside updateTaskAssignment's mutateBoard lock.
|
|
773
853
|
input.expectedLeaseId !== void 0 ? { expectedLeaseId: input.expectedLeaseId } : {}
|
|
774
854
|
);
|
|
775
|
-
|
|
855
|
+
if (!board) return fail("Task not found.");
|
|
856
|
+
if (assignmentStatus === "completed") {
|
|
857
|
+
const envGate = readEnvGateEnforcement();
|
|
858
|
+
const finalized = await finalizeTaskCompletion(projectRoot, board.id, input.taskId, {
|
|
859
|
+
...board.completionGate === void 0 && envGate !== void 0 ? { enforcement: envGate } : {},
|
|
860
|
+
...ctx.agentId !== void 0 ? { eventContext: { actor: ctx.agentId } } : {}
|
|
861
|
+
});
|
|
862
|
+
if (finalized) {
|
|
863
|
+
if (finalized.gate.report) {
|
|
864
|
+
recordKanbanVerificationEvidence(ctx, finalized.gate.report);
|
|
865
|
+
}
|
|
866
|
+
const gateSummary = {
|
|
867
|
+
enforcement: finalized.gate.enforcement,
|
|
868
|
+
allowed: finalized.gate.allowed,
|
|
869
|
+
verdict: finalized.gate.verdict,
|
|
870
|
+
issues: finalized.gate.issues.map((issue) => issue.message)
|
|
871
|
+
};
|
|
872
|
+
const gateMessage = finalized.gate.allowed ? `Completion gate ${finalized.gate.verdict === "skipped" ? "skipped" : "passed"}; task completed.` : finalized.gate.enforcement === "strict" ? `Completion gate BLOCKED (verdict: ${finalized.gate.verdict}); task parked in review. Issues: ${gateSummary.issues.join(" | ")}` : `Completion gate failed softly (verdict: ${finalized.gate.verdict}); task completed with warnings. Issues: ${gateSummary.issues.join(" | ")}`;
|
|
873
|
+
return {
|
|
874
|
+
...okTask(finalized.board, finalized.task, `Assignment updated. ${gateMessage}`),
|
|
875
|
+
gate: gateSummary
|
|
876
|
+
};
|
|
877
|
+
}
|
|
878
|
+
}
|
|
879
|
+
return okBoard(board, "Assignment updated.");
|
|
776
880
|
}
|
|
777
881
|
case "heartbeat_assignment": {
|
|
778
882
|
if (!input.boardId || !input.taskId) {
|
|
@@ -936,6 +1040,49 @@ var kanbanTool = {
|
|
|
936
1040
|
});
|
|
937
1041
|
return board ? okBoard(board, "Link added.") : fail("Task not found.");
|
|
938
1042
|
}
|
|
1043
|
+
case "assess_atomicity": {
|
|
1044
|
+
if (!input.boardId || !input.taskId) {
|
|
1045
|
+
return fail("assess_atomicity requires boardId and taskId.");
|
|
1046
|
+
}
|
|
1047
|
+
const result2 = await assessTaskAtomicity(projectRoot, input.boardId, input.taskId, {
|
|
1048
|
+
assessedBy: "agent",
|
|
1049
|
+
...ctx.agentId !== void 0 ? { eventContext: { actor: ctx.agentId } } : {}
|
|
1050
|
+
});
|
|
1051
|
+
if (!result2) return fail("Task not found.");
|
|
1052
|
+
const failing = result2.assessment.criteria.filter((entry) => entry.score < 1).map((entry) => entry.reason);
|
|
1053
|
+
const guidance = result2.assessment.verdict === "needs_decomposition" ? ` This task should be split before dispatch \u2014 call propose_decomposition with 2+ subtasks (each with one verifiable success criterion). Reasons: ${failing.join(" | ")}` : result2.assessment.verdict === "composite" ? " Container task: work happens in its children; it is verified via subtask aggregation." : "";
|
|
1054
|
+
return okTask(
|
|
1055
|
+
result2.board,
|
|
1056
|
+
result2.task,
|
|
1057
|
+
`Atomicity verdict: ${result2.assessment.verdict} (score ${result2.assessment.score}).${guidance}`
|
|
1058
|
+
);
|
|
1059
|
+
}
|
|
1060
|
+
case "propose_decomposition": {
|
|
1061
|
+
if (!input.boardId || !input.taskId || !input.subtasks?.length) {
|
|
1062
|
+
return fail("propose_decomposition requires boardId, taskId, and subtasks (2+).");
|
|
1063
|
+
}
|
|
1064
|
+
if (input.subtasks.length < 2) {
|
|
1065
|
+
return fail("propose_decomposition requires at least two subtasks.");
|
|
1066
|
+
}
|
|
1067
|
+
const invalid = input.subtasks.find(
|
|
1068
|
+
(subtask) => typeof subtask?.title !== "string" || !subtask.title.trim()
|
|
1069
|
+
);
|
|
1070
|
+
if (invalid) return fail("Every proposed subtask needs a non-blank title.");
|
|
1071
|
+
const result2 = await proposeTaskDecomposition(
|
|
1072
|
+
projectRoot,
|
|
1073
|
+
input.boardId,
|
|
1074
|
+
input.taskId,
|
|
1075
|
+
{
|
|
1076
|
+
subtasks: input.subtasks,
|
|
1077
|
+
...input.note !== void 0 ? { rationale: input.note } : {},
|
|
1078
|
+
...ctx.agentId !== void 0 ? { proposedBy: ctx.agentId } : {}
|
|
1079
|
+
},
|
|
1080
|
+
ctx.agentId !== void 0 ? { actor: ctx.agentId } : {}
|
|
1081
|
+
);
|
|
1082
|
+
if (!result2) return fail("Task not found.");
|
|
1083
|
+
const message = result2.proposal.status === "applied" ? `Decomposition applied: ${result2.proposal.appliedChildTaskIds?.length ?? 0} child tasks created (parent marked atomic).` : 'Decomposition proposal recorded \u2014 awaiting approval (board policy is "propose"). It can be approved from the WebUI or via update_task.';
|
|
1084
|
+
return okTask(result2.board, result2.task, message);
|
|
1085
|
+
}
|
|
939
1086
|
case "verify_completion": {
|
|
940
1087
|
if (!input.boardId || !input.taskId) {
|
|
941
1088
|
return fail("verify_completion requires boardId and taskId.");
|
|
@@ -953,6 +1100,7 @@ var kanbanTool = {
|
|
|
953
1100
|
board: verResult.board
|
|
954
1101
|
};
|
|
955
1102
|
}
|
|
1103
|
+
recordKanbanVerificationEvidence(ctx, verResult.report);
|
|
956
1104
|
const freshTask = persistedBoard.tasks?.find((t) => t.id === input.taskId);
|
|
957
1105
|
const deterministicVerdicts = ["passed", "failed", "needs_human", "incomplete"];
|
|
958
1106
|
return {
|
|
@@ -979,6 +1127,15 @@ var kanbanTool = {
|
|
|
979
1127
|
}
|
|
980
1128
|
}
|
|
981
1129
|
};
|
|
1130
|
+
function atomicityNudge(task) {
|
|
1131
|
+
if (task.atomicityAssessment?.verdict !== "needs_decomposition") return "";
|
|
1132
|
+
const reasons = task.atomicityAssessment.criteria.filter((entry) => entry.score < 1).map((entry) => entry.reason).join(" | ");
|
|
1133
|
+
return ` Atomicity: needs_decomposition (score ${task.atomicityAssessment.score}) \u2014 call propose_decomposition with 2+ subtasks before dispatch. Reasons: ${reasons}`;
|
|
1134
|
+
}
|
|
1135
|
+
function readEnvGateEnforcement() {
|
|
1136
|
+
const raw = process.env["WRONGSTACK_KANBAN_GATE"]?.trim().toLowerCase();
|
|
1137
|
+
return raw === "strict" || raw === "soft" || raw === "off" ? raw : void 0;
|
|
1138
|
+
}
|
|
982
1139
|
function fail(message) {
|
|
983
1140
|
return { ok: false, message };
|
|
984
1141
|
}
|