board: /tasks confirms a candidate into an open task (V-511)

The candidate row is now an intake form, not a button. Confirming asks for a
definition of done and refuses without one, takes an optional blocked-on name,
and carries the date and the importance through.

The blocked-on is a name in the form and a canonical nexus id in the store.
promoteCandidate resolves it over the new ipc.ResolveEntity seam and stops the
confirmation on an ambiguous or unplaceable name rather than picking.

A date set here books a reminder for 09:00 that morning. That is the only
unprompted delivery the persona allows, because the owner set the date himself.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SoL7EBdYC5Mhz3DJd49GJy
This commit is contained in:
2026-08-05 20:46:35 +04:00
parent cb350efb19
commit 570b204571
3 changed files with 104 additions and 5 deletions
+6 -2
View File
@@ -77,10 +77,14 @@ func TestHandleTasksSplitsCandidatesFromOpen(t *testing.T) {
t.Errorf("body missing %q", want)
}
}
// The candidate must offer confirm, and the open task must not.
if !strings.Contains(body, "value=confirm") {
// The candidate must offer the intake form, and it asks for a definition of
// done before it will confirm anything (V-511).
if !strings.Contains(body, "value=promote") {
t.Error("candidate row has no confirm action")
}
if !strings.Contains(body, "name=done_when") {
t.Error("the confirm form does not ask for a definition of done")
}
}
func TestHandleTasksAddCaptures(t *testing.T) {