Add STEP_DONE guards, verdict storage, and stale delivery suppression
This commit is contained in:
@@ -119,6 +119,10 @@ export function applyBaseSchema(database: Database): void {
|
||||
review_requested_at TEXT,
|
||||
round_trip_count INTEGER NOT NULL DEFAULT 0,
|
||||
owner_failure_count INTEGER NOT NULL DEFAULT 0,
|
||||
owner_step_done_streak INTEGER NOT NULL DEFAULT 0,
|
||||
finalize_step_done_count INTEGER NOT NULL DEFAULT 0,
|
||||
task_done_then_user_reopen_count INTEGER NOT NULL DEFAULT 0,
|
||||
empty_step_done_streak INTEGER NOT NULL DEFAULT 0,
|
||||
status TEXT NOT NULL DEFAULT 'active',
|
||||
arbiter_verdict TEXT,
|
||||
arbiter_requested_at TEXT,
|
||||
@@ -154,6 +158,7 @@ export function applyBaseSchema(database: Database): void {
|
||||
turn_number INTEGER NOT NULL,
|
||||
role TEXT NOT NULL,
|
||||
output_text TEXT NOT NULL,
|
||||
verdict TEXT,
|
||||
created_at TEXT NOT NULL,
|
||||
UNIQUE(task_id, turn_number, role)
|
||||
);
|
||||
|
||||
@@ -36,6 +36,7 @@ function getExpectedSchemaMigrations(): Array<{
|
||||
{ version: 9, name: 'paired_workspace_project_schema_cleanup' },
|
||||
{ version: 10, name: 'paired_turn_provenance_upgrade' },
|
||||
{ version: 11, name: 'owner_failure_count' },
|
||||
{ version: 12, name: 'paired_verdict_and_step_telemetry' },
|
||||
];
|
||||
}
|
||||
|
||||
|
||||
75
src/db/migrations/012_paired-verdict-and-step-telemetry.ts
Normal file
75
src/db/migrations/012_paired-verdict-and-step-telemetry.ts
Normal file
@@ -0,0 +1,75 @@
|
||||
import type { Database } from 'bun:sqlite';
|
||||
|
||||
import { tableHasColumn } from './helpers.js';
|
||||
import type { SchemaMigrationDefinition } from './types.js';
|
||||
|
||||
export const PAIRED_VERDICT_AND_STEP_TELEMETRY_MIGRATION: SchemaMigrationDefinition =
|
||||
{
|
||||
version: 12,
|
||||
name: 'paired_verdict_and_step_telemetry',
|
||||
apply(database: Database) {
|
||||
if (!tableHasColumn(database, 'paired_turn_outputs', 'verdict')) {
|
||||
database.exec(`
|
||||
ALTER TABLE paired_turn_outputs
|
||||
ADD COLUMN verdict TEXT
|
||||
`);
|
||||
}
|
||||
|
||||
if (!tableHasColumn(database, 'paired_tasks', 'owner_step_done_streak')) {
|
||||
database.exec(`
|
||||
ALTER TABLE paired_tasks
|
||||
ADD COLUMN owner_step_done_streak INTEGER NOT NULL DEFAULT 0
|
||||
`);
|
||||
}
|
||||
|
||||
if (
|
||||
!tableHasColumn(database, 'paired_tasks', 'finalize_step_done_count')
|
||||
) {
|
||||
database.exec(`
|
||||
ALTER TABLE paired_tasks
|
||||
ADD COLUMN finalize_step_done_count INTEGER NOT NULL DEFAULT 0
|
||||
`);
|
||||
}
|
||||
|
||||
if (
|
||||
!tableHasColumn(
|
||||
database,
|
||||
'paired_tasks',
|
||||
'task_done_then_user_reopen_count',
|
||||
)
|
||||
) {
|
||||
database.exec(`
|
||||
ALTER TABLE paired_tasks
|
||||
ADD COLUMN task_done_then_user_reopen_count INTEGER NOT NULL DEFAULT 0
|
||||
`);
|
||||
}
|
||||
|
||||
if (!tableHasColumn(database, 'paired_tasks', 'empty_step_done_streak')) {
|
||||
database.exec(`
|
||||
ALTER TABLE paired_tasks
|
||||
ADD COLUMN empty_step_done_streak INTEGER NOT NULL DEFAULT 0
|
||||
`);
|
||||
}
|
||||
|
||||
database.exec(`
|
||||
UPDATE paired_tasks
|
||||
SET owner_step_done_streak = 0
|
||||
WHERE owner_step_done_streak IS NULL
|
||||
`);
|
||||
database.exec(`
|
||||
UPDATE paired_tasks
|
||||
SET finalize_step_done_count = 0
|
||||
WHERE finalize_step_done_count IS NULL
|
||||
`);
|
||||
database.exec(`
|
||||
UPDATE paired_tasks
|
||||
SET task_done_then_user_reopen_count = 0
|
||||
WHERE task_done_then_user_reopen_count IS NULL
|
||||
`);
|
||||
database.exec(`
|
||||
UPDATE paired_tasks
|
||||
SET empty_step_done_streak = 0
|
||||
WHERE empty_step_done_streak IS NULL
|
||||
`);
|
||||
},
|
||||
};
|
||||
@@ -11,6 +11,7 @@ import { PAIRED_TASK_SCHEMA_CLEANUP_MIGRATION } from './008_paired-task-schema-c
|
||||
import { PAIRED_WORKSPACE_PROJECT_SCHEMA_CLEANUP_MIGRATION } from './009_paired-workspace-project-schema-cleanup.js';
|
||||
import { PAIRED_TURN_PROVENANCE_UPGRADE_MIGRATION } from './010_paired-turn-provenance-upgrade.js';
|
||||
import { OWNER_FAILURE_COUNT_MIGRATION } from './011_owner-failure-count.js';
|
||||
import { PAIRED_VERDICT_AND_STEP_TELEMETRY_MIGRATION } from './012_paired-verdict-and-step-telemetry.js';
|
||||
import type {
|
||||
SchemaMigrationArgs,
|
||||
SchemaMigrationDefinition,
|
||||
@@ -30,6 +31,7 @@ const ORDERED_SCHEMA_MIGRATIONS: readonly SchemaMigrationDefinition[] = [
|
||||
PAIRED_WORKSPACE_PROJECT_SCHEMA_CLEANUP_MIGRATION,
|
||||
PAIRED_TURN_PROVENANCE_UPGRADE_MIGRATION,
|
||||
OWNER_FAILURE_COUNT_MIGRATION,
|
||||
PAIRED_VERDICT_AND_STEP_TELEMETRY_MIGRATION,
|
||||
];
|
||||
|
||||
function ensureSchemaMigrationsTable(database: Database): void {
|
||||
|
||||
@@ -51,6 +51,10 @@ export type PairedTaskUpdates = Partial<
|
||||
| 'review_requested_at'
|
||||
| 'round_trip_count'
|
||||
| 'owner_failure_count'
|
||||
| 'owner_step_done_streak'
|
||||
| 'finalize_step_done_count'
|
||||
| 'task_done_then_user_reopen_count'
|
||||
| 'empty_step_done_streak'
|
||||
| 'status'
|
||||
| 'arbiter_verdict'
|
||||
| 'arbiter_requested_at'
|
||||
@@ -173,6 +177,10 @@ export function createPairedTaskInDatabase(
|
||||
review_requested_at,
|
||||
round_trip_count,
|
||||
owner_failure_count,
|
||||
owner_step_done_streak,
|
||||
finalize_step_done_count,
|
||||
task_done_then_user_reopen_count,
|
||||
empty_step_done_streak,
|
||||
status,
|
||||
arbiter_verdict,
|
||||
arbiter_requested_at,
|
||||
@@ -180,7 +188,7 @@ export function createPairedTaskInDatabase(
|
||||
created_at,
|
||||
updated_at
|
||||
)
|
||||
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
||||
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
||||
`,
|
||||
)
|
||||
.run(
|
||||
@@ -198,6 +206,10 @@ export function createPairedTaskInDatabase(
|
||||
task.review_requested_at,
|
||||
task.round_trip_count,
|
||||
task.owner_failure_count ?? 0,
|
||||
task.owner_step_done_streak ?? 0,
|
||||
task.finalize_step_done_count ?? 0,
|
||||
task.task_done_then_user_reopen_count ?? 0,
|
||||
task.empty_step_done_streak ?? 0,
|
||||
task.status,
|
||||
task.arbiter_verdict,
|
||||
task.arbiter_requested_at,
|
||||
@@ -306,6 +318,22 @@ export function updatePairedTaskInDatabase(
|
||||
fields.push('owner_failure_count = ?');
|
||||
values.push(updates.owner_failure_count);
|
||||
}
|
||||
if (updates.owner_step_done_streak !== undefined) {
|
||||
fields.push('owner_step_done_streak = ?');
|
||||
values.push(updates.owner_step_done_streak);
|
||||
}
|
||||
if (updates.finalize_step_done_count !== undefined) {
|
||||
fields.push('finalize_step_done_count = ?');
|
||||
values.push(updates.finalize_step_done_count);
|
||||
}
|
||||
if (updates.task_done_then_user_reopen_count !== undefined) {
|
||||
fields.push('task_done_then_user_reopen_count = ?');
|
||||
values.push(updates.task_done_then_user_reopen_count);
|
||||
}
|
||||
if (updates.empty_step_done_streak !== undefined) {
|
||||
fields.push('empty_step_done_streak = ?');
|
||||
values.push(updates.empty_step_done_streak);
|
||||
}
|
||||
if (updates.status !== undefined) {
|
||||
fields.push('status = ?');
|
||||
values.push(updates.status);
|
||||
@@ -369,6 +397,22 @@ export function updatePairedTaskIfUnchangedInDatabase(
|
||||
fields.push('owner_failure_count = ?');
|
||||
values.push(updates.owner_failure_count);
|
||||
}
|
||||
if (updates.owner_step_done_streak !== undefined) {
|
||||
fields.push('owner_step_done_streak = ?');
|
||||
values.push(updates.owner_step_done_streak);
|
||||
}
|
||||
if (updates.finalize_step_done_count !== undefined) {
|
||||
fields.push('finalize_step_done_count = ?');
|
||||
values.push(updates.finalize_step_done_count);
|
||||
}
|
||||
if (updates.task_done_then_user_reopen_count !== undefined) {
|
||||
fields.push('task_done_then_user_reopen_count = ?');
|
||||
values.push(updates.task_done_then_user_reopen_count);
|
||||
}
|
||||
if (updates.empty_step_done_streak !== undefined) {
|
||||
fields.push('empty_step_done_streak = ?');
|
||||
values.push(updates.empty_step_done_streak);
|
||||
}
|
||||
if (updates.status !== undefined) {
|
||||
fields.push('status = ?');
|
||||
values.push(updates.status);
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import { Database } from 'bun:sqlite';
|
||||
|
||||
import { logger } from '../logger.js';
|
||||
import { parseVisibleVerdict } from '../paired-verdict.js';
|
||||
import { PairedRoomRole, PairedTurnOutput } from '../types.js';
|
||||
|
||||
const MAX_TURN_OUTPUT_CHARS = 50_000;
|
||||
@@ -29,14 +30,15 @@ export function insertPairedTurnOutputInDatabase(
|
||||
database
|
||||
.prepare(
|
||||
`INSERT OR REPLACE INTO paired_turn_outputs
|
||||
(task_id, turn_number, role, output_text, created_at)
|
||||
VALUES (?, ?, ?, ?, ?)`,
|
||||
(task_id, turn_number, role, output_text, verdict, created_at)
|
||||
VALUES (?, ?, ?, ?, ?, ?)`,
|
||||
)
|
||||
.run(
|
||||
taskId,
|
||||
turnNumber,
|
||||
role,
|
||||
outputText.slice(0, MAX_TURN_OUTPUT_CHARS),
|
||||
parseVisibleVerdict(outputText),
|
||||
createdAt ?? new Date().toISOString(),
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user