mirror of
https://github.com/paperclipai/paperclip.git
synced 2026-11-05 21:02:34 +01:00
Merge current master lifecycle and CI fixes into Claude behavior
Co-Authored-By: Paperclip <noreply@paperclip.ing> * codex/claude-runner-protocol: fix(grok): avoid routine wakes for proactive admission (#16422) feat(ci): profile full CODEOWNER PR suites in Honeycomb (#16378) test: bound command snapshot forwarding checks (#16421) fix(agents): report actionable lifecycle failure steps (#16418)
This commit is contained in:
commit
bd3ceab2b2
50 files changed
+1630
-60
No files matched your search
@@ -8,6 +8,22 @@ describe("saved harness verification", () => {
|
||||
adapterType: "test", status, testedAt: new Date().toISOString(),
|
||||
checks: codes.map(code => ({ code, level: "info", message: code })),
|
||||
});
|
||||
it.each([
|
||||
["opencode_hello_probe_auth_required", "harness_auth_failed"],
|
||||
["opencode_hello_probe_model_unavailable", "harness_model_unavailable"],
|
||||
["opencode_command_unresolvable", "harness_command_unavailable"],
|
||||
["opencode_cwd_invalid", "harness_cwd_invalid"],
|
||||
["opencode_hello_probe_timed_out", "harness_probe_timed_out"],
|
||||
["opencode_hello_probe_unexpected_output", "harness_probe_unexpected_output"],
|
||||
["private provider error", "harness_test_failed"],
|
||||
])("classifies %s without keeping provider output", (checkCode, code) => {
|
||||
try {
|
||||
assertHarnessTestPassed(result("fail", [checkCode]));
|
||||
expect.fail("Expected verification to fail");
|
||||
} catch (error) {
|
||||
expect(error).toMatchObject({ code, message: "The harness test failed" });
|
||||
}
|
||||
});
|
||||
it.each([
|
||||
["fail", []], ["warn", ["claude_hello_probe_auth_required"]],
|
||||
["warn", ["gemini_hello_probe_timed_out"]], ["pass", ["claude_hello_probe_skipped_custom_command"]],
|
||||
|
||||
@@ -243,6 +243,9 @@ describe("durable Dot Runner integration", () => {
|
||||
try {
|
||||
const requests = await Promise.all([1, 2, 3].map(() => f.broker.requestTurn(f.principal, "Create hello and assign it to my owner", requestId)));
|
||||
expect(requests[1]).toEqual(requests[0]); expect(requests[2]).toEqual(requests[0]);
|
||||
expect(requests[0]!.instruction).toContain(provider === "grok_bot"
|
||||
? "Queued admission does not start another Grok routine"
|
||||
: "Events also notify queued work");
|
||||
const intake = await db.select().from(issues).where(eq(issues.id, requests[0]!.issueId));
|
||||
expect(intake).toHaveLength(1);
|
||||
expect(intake[0]).toMatchObject({ assigneeAgentId: f.agent.id, createdByAgentId: f.agent.id, responsibleUserId: f.userId });
|
||||
|
||||
@@ -289,6 +289,28 @@ describe("durable Grok routine qualification", () => {
|
||||
expect((await dotRunnerBroker(db).read(f.principal, work.id)).toolUsageInstructions).toContain("paperclip_grok_operation_status");
|
||||
});
|
||||
|
||||
it.each(["new offer", "prepared before restart"] as const)("does not echo delayed Bot-initiated work: %s", async scenario => {
|
||||
const f = await fixture(); const { work, run } = await admittedWork(f, "offered");
|
||||
await db.update(heartbeatRuns).set({ contextSnapshot: { grokProactiveRequest: {
|
||||
requestId: randomUUID(), bindingId: f.pairing.bindingId, bindingGeneration: 1,
|
||||
} } }).where(eq(heartbeatRuns.id, run.id));
|
||||
await db.update(dotRunnerAssignments).set({ createdAt: new Date(Date.now() - 60_000) }).where(eq(dotRunnerAssignments.id, work.id));
|
||||
const legacy = scenario === "prepared before restart" ? await f.service.reserve({
|
||||
companyId: f.company.id, agentId: f.agent.id, bindingId: f.pairing.bindingId,
|
||||
assignmentId: work.id, kind: "mailbox_updated", sourceEventId: `proactive-admission:${work.id}`,
|
||||
}) : null;
|
||||
f.delivery.mockClear(); const dispatcher = createGrokRoutineDispatcher(db, () => true, f.delivery);
|
||||
await dispatcher.tick(); await dispatcher.tick();
|
||||
expect(f.delivery).not.toHaveBeenCalled();
|
||||
const wakes = await db.select().from(grokBotDispatches).where(eq(grokBotDispatches.assignmentId, work.id));
|
||||
if (legacy) expect(wakes).toEqual([expect.objectContaining({ id: legacy.id, status: "cancelled" })]);
|
||||
else expect(wakes).toEqual([]);
|
||||
// The original conversation still owns and can accept the polled offer.
|
||||
await expect(dotRunnerBroker(db).read(f.principal, work.id)).resolves.toBeDefined();
|
||||
await (await acceptance(f, work))();
|
||||
expect((await db.select().from(dotRunnerAssignments).where(eq(dotRunnerAssignments.id, work.id)))[0]?.status).toBe("accepted");
|
||||
});
|
||||
|
||||
it("cancels a queued wake when its assignment was already accepted", async () => {
|
||||
const f = await fixture(); const { work } = await admittedWork(f, "offered");
|
||||
const queued = await f.service.reserve({ companyId: f.company.id, agentId: f.agent.id,
|
||||
|
||||
Reference in new issue
Block a user