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

View File

@@ -0,0 +1,69 @@
import { Schema } from "effect";
export const WorkStatus = Schema.Literals([
"proposed",
"defining",
"awaiting-definition-approval",
"designing",
"awaiting-design-approval",
"ready",
"executing",
"needs-input",
"blocked",
"completed",
"failed",
"cancelled",
]);
export type WorkStatus = typeof WorkStatus.Type;
export const WORK_TRANSITIONS: Readonly<
Record<WorkStatus, readonly WorkStatus[]>
> = {
"awaiting-definition-approval": ["designing", "defining"],
"awaiting-design-approval": [
"ready",
"designing",
"awaiting-definition-approval",
],
blocked: ["ready", "executing", "cancelled"],
cancelled: ["ready", "proposed"],
completed: ["proposed", "defining"],
defining: ["awaiting-definition-approval", "proposed"],
designing: ["awaiting-design-approval", "awaiting-definition-approval"],
executing: [
"ready",
"needs-input",
"blocked",
"completed",
"failed",
"cancelled",
],
failed: ["ready", "executing", "cancelled"],
"needs-input": ["ready", "executing", "cancelled"],
proposed: ["defining"],
ready: ["executing", "designing", "cancelled"],
};
export const canTransitionWork = (from: WorkStatus, to: WorkStatus): boolean =>
WORK_TRANSITIONS[from].includes(to);
export const assertWorkTransition = (
from: WorkStatus,
to: WorkStatus
): void => {
if (!canTransitionWork(from, to)) {
throw new Error(`Invalid Work transition: ${from} -> ${to}`);
}
};
export const definitionRevisionInvalidation = {
definitionApproval: "invalidate" as const,
dependentDesign: "invalidate" as const,
designApproval: "invalidate" as const,
workStatus: "defining" as const,
};
export const designRevisionInvalidation = {
designApproval: "invalidate" as const,
workStatus: "designing" as const,
};