Slices 2-4: Work becomes executable

Domain primitives: versioned WorkDefinition/DesignPacket with risk, questions,
and approval gates; lifecycle transition table with invalidation rules;
Resolver (Run/Attempt/outcomes/CodingKitV0); provider-neutral HarnessRuntime
with normalized events and a deterministic FakeHarnessLive that always reaches
a terminal classification and never claims implementation.

Convex durable model: workDefinitions, workQuestions, workApprovals,
designPackets, workSlices, workRuns, workAttempts, workAttemptEvents tables;
broadened works.status union; generalized workEvents with optional signalId,
referenceId, and payloadJson. Authenticated commands for definition request/
save/revise/approve, question answer/withdraw, design save/revise/approve, and
simulated execution start/cancel/retry with leased attempts, checkpointed
events, and expired-lease reconciliation.

Private work-planner FLUE agent with proposal-only tools (definition, design,
question). Convex validates and stores every proposal; FLUE never approves or
advances Work.

Expanded Work card with Outcome, Design, and Build sections wired to the new
mutations. Slice 1 conversation and provenance preserved.
This commit is contained in:
-Puter
2026-07-27 22:52:14 +05:30
parent cb7484912c
commit 005b26fa32
19 changed files with 2480 additions and 13 deletions
+69
View File
@@ -0,0 +1,69 @@
import { parseAgentEnv } from "@code/env/agent";
import { defineTool } from "@flue/runtime";
import { ConvexHttpClient } from "convex/browser";
import { makeFunctionReference } from "convex/server";
import * as v from "valibot";
const submitDefinitionRef = makeFunctionReference<
"mutation",
{ workId: string; payloadJson: string; token: string },
{ version: number }
>("workPlanning:submitDefinitionProposal");
const submitDesignRef = makeFunctionReference<
"mutation",
{ workId: string; payloadJson: string; token: string },
{ version: number }
>("workPlanning:submitDesignProposal");
const submitQuestionRef = makeFunctionReference<
"mutation",
{ workId: string; questionJson: string; token: string },
{ accepted: boolean }
>("workPlanning:submitQuestion");
export const createWorkPlannerTools = (
runtimeEnv: Record<string, string | undefined>
) => {
const env = parseAgentEnv(runtimeEnv);
const client = new ConvexHttpClient(env.CONVEX_URL);
const token = env.FLUE_DB_TOKEN;
return [
defineTool({
description:
"Submit a versioned Work Definition proposal. This never approves the Definition.",
input: v.object({ definitionJson: v.string(), workId: v.string() }),
name: "submit_definition_proposal",
async run({ input }) {
return await client.mutation(submitDefinitionRef, {
payloadJson: input.definitionJson,
token,
workId: input.workId,
});
},
}),
defineTool({
description:
"Submit a Design Packet with observable independently verifiable slices. This never approves the Design.",
input: v.object({ designJson: v.string(), workId: v.string() }),
name: "submit_design_proposal",
async run({ input }) {
return await client.mutation(submitDesignRef, {
payloadJson: input.designJson,
token,
workId: input.workId,
});
},
}),
defineTool({
description: "Submit one structured question for human attention.",
input: v.object({ questionJson: v.string(), workId: v.string() }),
name: "submit_question",
async run({ input }) {
return await client.mutation(submitQuestionRef, {
questionJson: input.questionJson,
token,
workId: input.workId,
});
},
}),
];
};