mirror of
https://github.com/paperclipai/paperclip.git
synced 2026-11-11 05:11:49 +01:00
Merge branch 'codex/dependable-repository-conversion' into codex/dependable-question-journey
* codex/dependable-repository-conversion: fix: defer saved native continuations behind their predecessor
This commit is contained in:
commit
4be3ebe335
8 files changed
+118
-8
No files matched your search
@@ -12,7 +12,9 @@ observer must download that source-attributed artifact while only the first
|
||||
admission is running, before the successor starts. A missing original, late
|
||||
observation, or different successor-created reference fails qualification. The
|
||||
successor is instructed to stop on a missing file and never recreate it. Both admissions
|
||||
must retain one workspace and commit their native results. The fixture uses
|
||||
must retain one workspace and commit their native results. The successor must
|
||||
have its own dispatch receipt and saved native intent. It starts after the
|
||||
predecessor finishes; dispatch must not retag the predecessor. The fixture uses
|
||||
production hire instructions and records the selected catalog model. These four
|
||||
development cells do not qualify Slack, staging configurations, migration,
|
||||
finalization restart, or the complete dependable-work milestone.
|
||||
|
||||
@@ -27,7 +27,7 @@ export async function runAutomaticRepositoryFlow(input: {
|
||||
const observation: AutomaticRepositoryObservation = { reference: "", issueDone: false, runCount: 0,
|
||||
successfulCommittedRuns: 0, sourceContinuation: null, successorSource: null, workspaceIds: [], readyRepository: false,
|
||||
savedContext: null, firstSavedContext: null, firstContextAttributed: false,
|
||||
firstContextObservedAt: null, successorStartedAt: null,
|
||||
firstContextObservedAt: null, successorStartedAt: null, predecessorFinishedAt: null, predecessorRetagged: true, continuationReceipt: null,
|
||||
actualReadme: null, actualCommit: null, downloaded: null, downloadVerified: false,
|
||||
visibleDelivery: false, pendingInteractions: -1, monitorScheduled: false };
|
||||
async function refresh() {
|
||||
@@ -44,6 +44,10 @@ export async function runAutomaticRepositoryFlow(input: {
|
||||
observation.sourceContinuation = runs[0]?.resultJson?.nativeResult?.continuation?.kind ?? null;
|
||||
observation.successorSource = runs[1]?.contextSnapshot?.source ?? null;
|
||||
observation.successorStartedAt = runs[1]?.startedAt ? Date.parse(runs[1].startedAt) : null;
|
||||
observation.predecessorFinishedAt = runs[0]?.finishedAt ? Date.parse(runs[0].finishedAt) : null;
|
||||
observation.predecessorRetagged = Boolean(runs[0]?.contextSnapshot?.nativeStatusWakeIntentId);
|
||||
const intentId = runs[1]?.contextSnapshot?.nativeStatusWakeIntentId, dispatchId = runs[1]?.wakeupRequestId;
|
||||
observation.continuationReceipt = typeof intentId === "string" && typeof dispatchId === "string" ? { intentId, dispatchId } : null;
|
||||
if (runs.length === 1 && runs[0]?.status === "running" && observation.firstContextObservedAt === null) {
|
||||
const original = await readRegisteredArtifacts(api, issue.id, runs[0].id, [files.context]).catch(() => null);
|
||||
if (original?.[0]) {
|
||||
|
||||
@@ -6,7 +6,8 @@ const reference = "c".repeat(64);
|
||||
const valid: AutomaticRepositoryObservation = { reference, issueDone: true, runCount: 2,
|
||||
successfulCommittedRuns: 2, sourceContinuation: "same_agent", successorSource: "native_status_decision", workspaceIds: ["workspace", "workspace"],
|
||||
readyRepository: true, savedContext: `${reference}\n`, firstSavedContext: `${reference}\n`, firstContextAttributed: true,
|
||||
firstContextObservedAt: 1000, successorStartedAt: 2000,
|
||||
firstContextObservedAt: 1000, successorStartedAt: 2000, predecessorFinishedAt: 1900, predecessorRetagged: false,
|
||||
continuationReceipt: { intentId: "11111111-1111-4111-8111-111111111111", dispatchId: "22222222-2222-4222-8222-222222222222" },
|
||||
actualReadme: "Hello World!\n", actualCommit: sha,
|
||||
downloaded: { reference, readme: "Hello World!\n", commit: sha }, downloadVerified: true,
|
||||
visibleDelivery: true, pendingInteractions: 0, monitorScheduled: false };
|
||||
@@ -36,7 +37,10 @@ it.each<Partial<AutomaticRepositoryObservation>>([
|
||||
{ workspaceIds: ["old", "new"] }, { savedContext: null }, { firstSavedContext: null }, { firstContextAttributed: false },
|
||||
{ firstSavedContext: `${"d".repeat(64)}\n` }, { firstSavedContext: "REFERENCE-fresh\n" },
|
||||
{ firstContextObservedAt: null }, { firstContextObservedAt: 2000 }, { firstContextObservedAt: 3000 }, { successorStartedAt: null },
|
||||
{ readyRepository: false }, { downloaded: null },
|
||||
{ readyRepository: false }, { downloaded: null }, { predecessorFinishedAt: null }, { predecessorFinishedAt: 2001 },
|
||||
{ predecessorRetagged: true }, { continuationReceipt: null },
|
||||
{ continuationReceipt: { ...valid.continuationReceipt!, dispatchId: valid.continuationReceipt!.intentId } },
|
||||
{ continuationReceipt: { ...valid.continuationReceipt!, intentId: "unverified" } },
|
||||
{ downloaded: { ...valid.downloaded, reference: "REFERENCE-stale" } },
|
||||
{ downloaded: { ...valid.downloaded, readme: "I inspected it and all checks pass" } },
|
||||
{ downloaded: { ...valid.downloaded, commit: "b".repeat(40) } },
|
||||
|
||||
@@ -42,6 +42,9 @@ export interface AutomaticRepositoryObservation {
|
||||
firstContextAttributed: boolean;
|
||||
firstContextObservedAt: number | null;
|
||||
successorStartedAt: number | null;
|
||||
predecessorFinishedAt: number | null;
|
||||
predecessorRetagged: boolean;
|
||||
continuationReceipt: { intentId: string; dispatchId: string } | null;
|
||||
actualReadme: string | null;
|
||||
actualCommit: string | null;
|
||||
downloaded: { reference?: unknown; readme?: unknown; commit?: unknown } | null;
|
||||
@@ -65,8 +68,13 @@ export function gradeAutomaticRepository(value: AutomaticRepositoryObservation)
|
||||
return [
|
||||
check("durable-completion", value.issueDone && value.runCount === 2 && value.successfulCommittedRuns === 2,
|
||||
"Two committed provider admissions must finish the requested result."),
|
||||
check("server-owned-continuation", value.sourceContinuation === "same_agent" && value.successorSource === "native_status_decision" && !value.monitorScheduled,
|
||||
"Repository setup must continue through the saved same-agent wake without a timer or user message."),
|
||||
check("server-owned-continuation", value.sourceContinuation === "same_agent" && value.successorSource === "native_status_decision" && !value.monitorScheduled &&
|
||||
!value.predecessorRetagged && value.predecessorFinishedAt !== null && value.successorStartedAt !== null &&
|
||||
value.successorStartedAt >= value.predecessorFinishedAt && value.continuationReceipt !== null &&
|
||||
/^[a-f0-9]{8}(?:-[a-f0-9]{4}){3}-[a-f0-9]{12}$/i.test(value.continuationReceipt.intentId) &&
|
||||
/^[a-f0-9]{8}(?:-[a-f0-9]{4}){3}-[a-f0-9]{12}$/i.test(value.continuationReceipt.dispatchId) &&
|
||||
value.continuationReceipt.intentId !== value.continuationReceipt.dispatchId,
|
||||
"The saved same-agent intent must bind a distinct successor dispatch after the unmodified predecessor finishes, without a timer or user message."),
|
||||
check("retained-workspace", value.workspaceIds.length === 2 && Boolean(value.workspaceIds[0]) && value.workspaceIds.every(id => id === value.workspaceIds[0]) && value.readyRepository,
|
||||
"Both admissions must retain the same task workspace and its prepared repository."),
|
||||
check("retained-context", value.firstContextAttributed && value.firstContextObservedAt !== null && value.successorStartedAt !== null &&
|
||||
|
||||
Reference in new issue
Block a user