mirror of
https://github.com/paperclipai/paperclip.git
synced 2026-11-11 05:11:49 +01:00
test: account for native cursor projection metadata
This commit is contained in:
1 parent
4917447393
commit
7e2e2a509e
5 files changed
+12
-6
No files matched your search
@@ -20,7 +20,7 @@ The opt-in DB SELECT evaluates every existing predicate as a named boolean colum
|
||||
|
||||
## Complete durable reason catalog
|
||||
|
||||
At this baseline there are 36 explicit checks, 32 retained-table checks, and four appended checks: 72 durable predicates. Keys identify domain families independently of SQL position or status. A later completion/ingress/deadline improvement retains the family key; a new independent predicate requires its own key and inventory row. This count is a baseline observation, not a permanent protocol limit.
|
||||
At this baseline there are 36 explicit checks, 32 retained-table checks, and four appended checks: 72 durable predicates. Keys identify domain families independently of SQL position or status. A later completion/ingress/deadline improvement retains the family key; a new independent predicate requires its own key and inventory row. This count is a baseline observation, not a permanent protocol limit. Native event cursor rebuilding adds the independent `native_event_cursor_rebuild` predicate, bringing the current total to 73.
|
||||
|
||||
For every row below, the diagnostic fixture is the named durable trigger and its negative/completion counterpart. Existing owner suites establish domain contracts; this PR's real PostgreSQL representative fixtures establish simultaneous reporting and the original eligibility behavior, not new exemptions for every domain. The reason-column test compiles the actual full policy query, checks key uniqueness, and evaluates its reporting contract. It is not substituted for real database fixtures or deployed proof.
|
||||
|
||||
@@ -32,6 +32,7 @@ Remedies below mean completing the owning protocol or supplying a separately tes
|
||||
| --- | --- | --- | --- |
|
||||
| `agents.execution_or_timer` | [agents](../../packages/db/src/schema/agents.ts); [heartbeat/scheduling.ts](../../server/src/services/heartbeat/scheduling.ts). active / future. | Running agent, or enabled positive timer on an executable agent. Paused/terminated/pending approval timers do not require dispatch. Fixture: Enable a positive timer; disable it for the negative fixture. | Future-work alarm coverage; preserve the owning evidence and records. |
|
||||
| `heartbeat_runs` | [heartbeat_runs](../../packages/db/src/schema/heartbeat_runs.ts); [heartbeat/run-completion.ts](../../server/src/services/heartbeat/run-completion.ts). active / recovery. | Nonterminal run, retry later than finish or missing finish, or pending accounting. Terminal consumed retries alone are history. Fixture: Queued run versus finished ordinary run, consumed retry, live retry child. | Domain settlement; preserve the owning evidence and records. |
|
||||
| `native_event_cursor_rebuild` | [heartbeat_runs](../../packages/db/src/schema/heartbeat_runs.ts); [heartbeat/native-event-cursor-work.ts](../../server/src/services/heartbeat/native-event-cursor-work.ts). projection recovery. | An explicitly pending native source cursor rebuild blocks sleep, including on a terminal run. Indexed pending state drains through bounded metadata pages. Fixture: Pending rebuild versus settled projection. | Complete the owned cursor rebuild; preserve event history and resume pending work after restart. |
|
||||
| `agent_instruction_working_copies` | [agent_instruction_working_copies](../../packages/db/src/schema/agent_instruction_revisions.ts); [agent-instruction-working-copies.ts](../../server/src/services/agent-instruction-working-copies.ts). cleanup. | Requires known settled state, stopped process, no next attempt, no baseline or cleanup-pending receipt. Fixture: Stopped saved copy versus deferred cleanup. | Domain cleanup; preserve the owning evidence and records. |
|
||||
| `sandbox_creation_operations` | [sandbox_creation_operations](../../packages/db/src/schema/sandbox_creation_operations.ts); [sandbox-creation-operations.ts](../../server/src/services/sandbox-creation-operations.ts). recovery. | Pending creation operation retains uncertain/provider work. Fixture: Pending operation versus settled operation. | Domain settlement; preserve the owning evidence and records. |
|
||||
| `budget_reservations` | [budget_reservations](../../packages/db/src/schema/accounting.ts); [budget-reservations.ts](../../server/src/services/budget-reservations.ts). accounting. | Anything outside settled/released remains owed. Fixture: Unsettled reservation versus settled charge. | Domain accounting; preserve the owning evidence and records. |
|
||||
|
||||
@@ -294,6 +294,10 @@ describeEmbeddedPostgres("merged Muse migration histories", () => {
|
||||
const beforeHistory = baseline === "fresh" ? [] : await historyRows(sql);
|
||||
const retainedRows = baseline === "fresh" ? null : await seedRetainedRows(sql, baseline === "muse0348");
|
||||
const beforeRows = await retainedRows?.();
|
||||
const expectedRows = beforeRows && {
|
||||
...beforeRows,
|
||||
run: { ...beforeRows.run, event_cursor_projection_seq: 0, event_cursor_rebuild_pending: false },
|
||||
};
|
||||
const state = await inspectMigrations(connectionString);
|
||||
expect(state.status).toBe("needsMigrations");
|
||||
const laterMigrations = journal.entries.filter(entry => entry.idx > 353).map(entry => `${entry.tag}.sql`);
|
||||
@@ -319,7 +323,7 @@ describeEmbeddedPostgres("merged Muse migration histories", () => {
|
||||
const currentHash = await migrationHash(entry.file);
|
||||
expect(afterHistory.filter(row => row.hash === currentHash)).toHaveLength(1);
|
||||
}
|
||||
if (retainedRows) expect(await retainedRows()).toEqual(beforeRows);
|
||||
if (retainedRows) expect(await retainedRows()).toEqual(expectedRows);
|
||||
const indexes = await sql`
|
||||
SELECT c.relname, i.indisvalid, i.indisready, pg_get_indexdef(c.oid) AS definition
|
||||
FROM pg_index i JOIN pg_class c ON c.oid = i.indexrelid JOIN pg_namespace n ON n.oid = c.relnamespace
|
||||
@@ -336,7 +340,7 @@ describeEmbeddedPostgres("merged Muse migration histories", () => {
|
||||
expect((await inspectMigrations(connectionString)).status).toBe("upToDate");
|
||||
expect(await historyRows(sql)).toEqual(afterHistory);
|
||||
expect(await schemaShape(sql)).toEqual(finalShape);
|
||||
if (retainedRows) expect(await retainedRows()).toEqual(beforeRows);
|
||||
if (retainedRows) expect(await retainedRows()).toEqual(expectedRows);
|
||||
} finally {
|
||||
await Promise.all([sql.end(), reference.end()]);
|
||||
}
|
||||
|
||||
@@ -61,7 +61,7 @@ if (!support.supported) console.warn(`Skipping idle sleep diagnostics Postgres t
|
||||
expect(blockers(report)).toEqual([]);
|
||||
expect(report.diagnostics?.checks.filter(check => !check.reason.includes(".") ||
|
||||
["agents.execution_or_timer", "agents.lifecycle", "agents.company_hold", "heartbeat_runs.budget_cancellation"].includes(check.reason)))
|
||||
.toHaveLength(72);
|
||||
.toHaveLength(73);
|
||||
expect(await db.select().from(heartbeatRuns).where(eq(heartbeatRuns.id, f.runId))).toHaveLength(1);
|
||||
});
|
||||
|
||||
|
||||
@@ -40,7 +40,7 @@ describe("owned idle sleep diagnostics", () => {
|
||||
expect(result.diagnostics?.complete).toBe(true);
|
||||
expect(result.diagnostics?.checks.filter(check => check.state === "present").map(check => check.reason))
|
||||
.toEqual(["agent_api_keys", "chat_deliveries", "heartbeat_runs", "muse_mailbox_items"]);
|
||||
expect(f.keys()).toHaveLength(72);
|
||||
expect(f.keys()).toHaveLength(73);
|
||||
expect(new Set(f.keys()).size).toBe(f.keys().length);
|
||||
const inventory = readFileSync(new URL("../../../doc/plans/2026-11-02-sleep-blocker-inventory.md", import.meta.url), "utf8");
|
||||
const documented = [...inventory.matchAll(/^\| `([a-z0-9_.]+)` \|/gm)].map(match => match[1]);
|
||||
|
||||
@@ -230,7 +230,8 @@ suite("settled native run process identity", () => {
|
||||
expect(summary.responseValueBytes).toBeLessThan(8192);
|
||||
const after = await readRun(runId);
|
||||
expect(after).toEqual({ ...saved, processPid: null, processGroupId: null, processStartedAt: null,
|
||||
nextEventSeq: saved.nextEventSeq + 1, updatedAt: after.updatedAt });
|
||||
nextEventSeq: saved.nextEventSeq + 1, eventCursorProjectionSeq: saved.eventCursorProjectionSeq + 1,
|
||||
updatedAt: after.updatedAt });
|
||||
expect(await hasNativeLocalProcessStop(db, companyId, runId)).toBe(true);
|
||||
expect(JSON.stringify(events)).not.toContain(bulk.slice(0, 64));
|
||||
});
|
||||
|
||||
Reference in new issue
Block a user