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

@@ -6,11 +6,15 @@ import {
import { Button } from "@code/ui/components/button";
import {
ChevronRight,
Check,
FolderGit2,
Hammer,
LoaderCircle,
Menu,
MessageSquareText,
ImagePlus,
Play,
RotateCcw,
Send,
Sparkles,
X,
@@ -34,11 +38,67 @@ const EMPTY_WORKS: readonly SliceWork[] = [];
interface WorkCardProps {
readonly onSourceSelect: (rawText: string) => void;
readonly work: SliceWork;
readonly slice: SliceOneState;
}
const WorkCard = ({ onSourceSelect, work }: WorkCardProps) => {
const starterDefinition = (work: SliceWork) => ({
acceptanceCriteria: ["The requested outcome is observable and documented"],
affectedUsers: ["Project users"],
assumptions: [],
constraints: [],
desiredOutcome: work.objective,
inScope: [work.objective],
outOfScope: ["Unrelated product changes"],
problem: work.objective,
questions: [],
requiredArtifacts: ["Simulation activity and terminal outcome"],
risk: "medium",
});
const starterDesign = (work: SliceWork) => ({
architectureSummary:
"Validate the approved Definition, then exercise one deterministic fake slice.",
callFlowDelta: [
"Work -> Run -> Attempt -> normalized events -> terminal outcome",
],
concerns: [],
evidenceRequirements: ["Terminal Run classification"],
fileTreeDelta: [],
impactMap: {
files: [],
modules: [],
risks: [],
summary: "Compact vertical-slice simulation",
},
invariants: [
"Simulation never claims implementation",
"Every Attempt reaches a terminal classification",
],
keyInterfaces: ["HarnessRuntime", "AttemptOutcome"],
slices: [
{
codeBoundaries: ["workExecution"],
dependsOn: [],
evidenceRequirements: ["Normalized activity events"],
id: "slice-1",
objective: work.objective,
observableBehavior: "A terminal fake Run is visible",
reviewRequired: false,
title: "Deterministic simulation",
verification: ["Run completes with a terminal classification"],
},
],
tradeoffs: ["Fake runtime proves contract before sandbox integration"],
});
// oxlint-disable-next-line complexity -- the expanded card intentionally keeps the three review sections together.
const WorkCard = ({ onSourceSelect, work, slice }: WorkCardProps) => {
const [sourcesOpen, setSourcesOpen] = useState(false);
const [expanded, setExpanded] = useState(false);
const sources = work.signals.flatMap((signal) => signal.sources);
const { definition } = work;
const { design } = work;
const [latestRun] = work.runs;
return (
<article className="border border-[#d7d3c7] bg-[#fffefa] p-4 text-[#20201d] shadow-[0_10px_30px_rgba(30,30,20,0.06)]">
<div className="flex items-start gap-3">
@@ -70,6 +130,16 @@ const WorkCard = ({ onSourceSelect, work }: WorkCardProps) => {
className={`size-4 transition-transform ${sourcesOpen ? "rotate-90" : ""}`}
/>
</button>
<button
className="mt-2 flex w-full items-center justify-between border-t border-[#e7e3d9] pt-3 text-left text-xs font-medium text-[#20201d]"
onClick={() => setExpanded((open) => !open)}
type="button"
>
<span>{expanded ? "Hide Work details" : "Open Work details"}</span>
<ChevronRight
className={`size-4 transition-transform ${expanded ? "rotate-90" : ""}`}
/>
</button>
{sourcesOpen ? (
<div className="mt-3 space-y-2">
{sources.map((source) => (
@@ -85,6 +155,156 @@ const WorkCard = ({ onSourceSelect, work }: WorkCardProps) => {
))}
</div>
) : null}
{expanded ? (
<div className="mt-4 space-y-4 border-t border-[#e7e3d9] pt-4 text-xs">
<section>
<p className="font-semibold uppercase tracking-wide text-[#65713a]">
Outcome
</p>
<p className="mt-1 leading-5 text-[#626057]">{work.objective}</p>
<p className="mt-2 text-[#747168]">
Risk: {definition?.risk ?? "not defined"}
</p>
{definition?.questions?.length ? (
<p className="mt-1 text-amber-800">
{
definition.questions.filter(
(question) => question.status === "open"
).length
}{" "}
open question(s)
</p>
) : null}
<div className="mt-2 flex flex-wrap gap-2">
{work.status === "proposed" ? (
<Button
size="sm"
onClick={() => void slice.requestDefinition(work._id)}
>
<Sparkles className="size-3.5" /> Define
</Button>
) : null}
{work.status === "defining" ? (
<Button
size="sm"
variant="outline"
onClick={() =>
void slice.saveDefinition(work._id, starterDefinition(work))
}
>
<Hammer className="size-3.5" /> Save definition
</Button>
) : null}
{work.status === "awaiting-definition-approval" &&
work.definitionVersion ? (
<Button
size="sm"
onClick={() =>
void slice.approveDefinition(
work._id,
work.definitionVersion as number
)
}
>
<Check className="size-3.5" /> Approve
</Button>
) : null}
</div>
</section>
<section>
<p className="font-semibold uppercase tracking-wide text-[#65713a]">
Design
</p>
<p className="mt-1 leading-5 text-[#626057]">
{design?.architectureSummary ?? "No Design Packet yet."}
</p>
{design?.slices?.map((item) => (
<p className="mt-1 text-[#747168]" key={item.id}>
{item.title}: {item.observableBehavior}
</p>
))}
<div className="mt-2 flex flex-wrap gap-2">
{work.status === "designing" ? (
<Button
size="sm"
variant="outline"
onClick={() =>
void slice.saveDesign(work._id, starterDesign(work))
}
>
<Hammer className="size-3.5" /> Save design
</Button>
) : null}
{work.status === "awaiting-design-approval" &&
work.definitionApprovalVersion &&
work.designVersion ? (
<Button
size="sm"
onClick={() =>
void slice.approveDesign(
work._id,
work.definitionApprovalVersion as number,
work.designVersion as number
)
}
>
<Check className="size-3.5" /> Approve design
</Button>
) : null}
</div>
</section>
<section>
<p className="font-semibold uppercase tracking-wide text-[#65713a]">
Build
</p>
{latestRun ? (
<p className="mt-1 leading-5 text-[#626057]">
Run {latestRun.status}:{" "}
{latestRun.terminalSummary ??
latestRun.terminalClassification ??
"activity is still arriving"}
</p>
) : (
<p className="mt-1 text-[#747168]">No simulation Run yet.</p>
)}
<div className="mt-2 flex flex-wrap gap-2">
{work.status === "ready" ? (
<Button
size="sm"
onClick={() =>
void slice.startSimulation(
work._id,
"success",
design?.slices?.[0]?.id
)
}
>
<Play className="size-3.5" /> Simulate
</Button>
) : null}
{latestRun?.status === "running" ? (
<Button
size="sm"
variant="outline"
onClick={() => void slice.cancelSimulation(latestRun._id)}
>
<X className="size-3.5" /> Cancel
</Button>
) : null}
{latestRun?.status === "terminal" &&
latestRun.terminalClassification === "RetryableFailure" ? (
<Button
size="sm"
variant="outline"
onClick={() => void slice.retrySimulation(latestRun._id)}
>
<RotateCcw className="size-3.5" /> Retry
</Button>
) : null}
</div>
</section>
</div>
) : null}
</article>
);
};
@@ -278,6 +498,7 @@ export const SliceOnePage = () => {
</p>
<WorkCard
onSourceSelect={revealSourceMessage}
slice={slice}
work={work}
/>
</div>
@@ -387,6 +608,7 @@ export const SliceOnePage = () => {
<WorkCard
key={work._id}
onSourceSelect={revealSourceMessage}
slice={slice}
work={work}
/>
))}
@@ -422,6 +644,7 @@ export const SliceOnePage = () => {
<WorkCard
key={work._id}
onSourceSelect={revealSourceMessage}
slice={slice}
work={work}
/>
))}

View File

@@ -1,6 +1,7 @@
import { api } from "@code/backend/convex/_generated/api";
import type { Id } from "@code/backend/convex/_generated/dataModel";
import { useAction, useQuery } from "convex/react";
import { useAction, useMutation, useQuery } from "convex/react";
import { makeFunctionReference } from "convex/server";
import { useMemo, useState } from "react";
import { useOrganizationChatAgent } from "@/hooks/chat/use-chat-agent";
@@ -9,6 +10,93 @@ import { usePersonalOrganization } from "@/hooks/use-personal-organization";
const toError = (error: unknown) =>
error instanceof Error ? error : new Error(String(error));
interface WorkRecord {
readonly _id: Id<"works">;
readonly title: string;
readonly objective: string;
readonly status: string;
readonly definitionVersion?: number;
readonly definitionApprovalVersion?: number;
readonly designVersion?: number;
readonly designApprovalVersion?: number;
readonly signals: readonly {
sources: readonly { messageId: string; rawText: string }[];
}[];
readonly events: readonly { _id: string; createdAt: number; kind: string }[];
readonly definitions: readonly unknown[];
readonly designs: readonly unknown[];
readonly slices: readonly unknown[];
readonly runs: readonly {
_id: Id<"workRuns">;
status: string;
terminalClassification?: string;
terminalSummary?: string;
}[];
readonly definition: {
risk?: string;
questions?: { status: string }[];
} | null;
readonly design: {
architectureSummary?: string;
slices?: { id: string; title: string; observableBehavior: string }[];
} | null;
}
const workListRef = makeFunctionReference<
"query",
{ projectId: Id<"projects"> },
WorkRecord[]
>("workPlanning:listForProject");
const requestDefinitionRef = makeFunctionReference<
"mutation",
{ workId: Id<"works"> },
unknown
>("workPlanning:requestDefinition");
const saveDefinitionRef = makeFunctionReference<
"mutation",
{ workId: Id<"works">; payloadJson: string },
unknown
>("workPlanning:saveDefinitionProposal");
const approveDefinitionRef = makeFunctionReference<
"mutation",
{ workId: Id<"works">; version: number },
unknown
>("workPlanning:approveDefinition");
const saveDesignRef = makeFunctionReference<
"mutation",
{ workId: Id<"works">; payloadJson: string },
unknown
>("workPlanning:saveDesignProposal");
const approveDesignRef = makeFunctionReference<
"mutation",
{ workId: Id<"works">; definitionVersion: number; designVersion: number },
unknown
>("workPlanning:approveDesign");
const startSimulationRef = makeFunctionReference<
"mutation",
{
workId: Id<"works">;
scenario:
| "success"
| "transient-failure-then-success"
| "needs-input"
| "permanent-failure"
| "cancelled";
sliceId?: string;
},
unknown
>("workExecution:startSimulatedExecution");
const cancelSimulationRef = makeFunctionReference<
"mutation",
{ runId: Id<"workRuns"> },
unknown
>("workExecution:cancelSimulatedExecution");
const retrySimulationRef = makeFunctionReference<
"mutation",
{ runId: Id<"workRuns"> },
unknown
>("workExecution:retrySimulatedExecution");
export const useSliceOne = () => {
const organization = usePersonalOrganization();
const projects = useQuery(
@@ -29,9 +117,17 @@ export const useSliceOne = () => {
? selectedProjectId
: ((projects?.[0]?.id as unknown as Id<"projects"> | undefined) ?? null);
const works = useQuery(
api.works.listForProject,
workListRef,
activeProjectId ? { projectId: activeProjectId } : "skip"
);
const requestDefinitionMutation = useMutation(requestDefinitionRef);
const saveDefinitionMutation = useMutation(saveDefinitionRef);
const approveDefinitionMutation = useMutation(approveDefinitionRef);
const saveDesignMutation = useMutation(saveDesignRef);
const approveDesignMutation = useMutation(approveDesignRef);
const startSimulationMutation = useMutation(startSimulationRef);
const cancelSimulationMutation = useMutation(cancelSimulationRef);
const retrySimulationMutation = useMutation(retrySimulationRef);
const selectedProject = useMemo(
() =>
projects?.find(
@@ -62,16 +158,52 @@ export const useSliceOne = () => {
setSelectedProjectId(projectId as unknown as Id<"projects">);
};
const requestDefinition = (workId: Id<"works">) =>
requestDefinitionMutation({ workId });
const saveDefinition = (workId: Id<"works">, payload: unknown) =>
saveDefinitionMutation({ payloadJson: JSON.stringify(payload), workId });
const approveDefinition = (workId: Id<"works">, version: number) =>
approveDefinitionMutation({ version, workId });
const saveDesign = (workId: Id<"works">, payload: unknown) =>
saveDesignMutation({ payloadJson: JSON.stringify(payload), workId });
const approveDesign = (
workId: Id<"works">,
definitionVersion: number,
designVersion: number
) => approveDesignMutation({ definitionVersion, designVersion, workId });
const startSimulation = (
workId: Id<"works">,
scenario:
| "success"
| "transient-failure-then-success"
| "needs-input"
| "permanent-failure"
| "cancelled",
sliceId?: string
) => startSimulationMutation({ scenario, sliceId, workId });
const cancelSimulation = (runId: Id<"workRuns">) =>
cancelSimulationMutation({ runId });
const retrySimulation = (runId: Id<"workRuns">) =>
retrySimulationMutation({ runId });
return {
agent,
approveDefinition,
approveDesign,
cancelSimulation,
connectRepository,
error,
pending,
projects,
repository,
requestDefinition,
retrySimulation,
saveDefinition,
saveDesign,
selectProject,
selectedProject,
setRepository,
startSimulation,
works,
} as const;
};