chore(compliance): drop agent_test_history + last_test_* — final cleanup#4274
Conversation
PR 5 of the #4247 unification stack. Removes the dual-write infrastructure now that PR #4250 writes canonically, PR #4264 backfilled history, and PR #4268 derives last_test_* via the agent_context_with_latest_test view. Migration 474 (gate-protected — destructive): - Redefines agent_context_summary without agent_test_history refs - Drops agent_contexts.last_test_* columns - Drops agent_test_history table - Refreshes agent_context_with_latest_test Code: - agent-context-db.ts drops recordTest, getTestHistory, getLatestTestForUser, AgentTestHistory, RecordTestInput - update() refetches via getById() so derived view fields stay populated - evaluate_agent_quality drops the third-party recordTest call - run_storyboard drops its recordTest call Behavior change: third-party evaluate_agent_quality and any run_storyboard call no longer persist registry state. Matches the owner-only canonical writes policy from #4247. Stacked on #4268 → #4264 → #4263 → #4250.
|
Code review (expert pass): block — final cleanup needs three fixes. 1. Verify 2. S3 export script is in the PR body, not in 3. Wrap migration 474 in an explicit transaction. Nit (non-blocking): |
Blocker fixes prepared — needs author to applyAll three blockers from @bokelley's review have been worked out. I can't push directly to Fix 1 — Two spots. The cascade concern is moot (no child tables remain); logic is unchanged. - // UNIQUE(organization_id, agent_url): keep primary's row on
- // conflict so its agent_test_history (ON DELETE CASCADE) survives;
- // secondary's history is removed when its row is deleted.
+ // UNIQUE(organization_id, agent_url): on conflict keep primary's
+ // row; secondary's conflicting rows are deleted below (no child
+ // tables remain after migration 474 dropped agent_test_history).- `${agentContextsDeleted.rows.length} duplicate agent_contexts from secondary org were deleted (primary already had the same agent_url) — their test history was removed`
+ `${agentContextsDeleted.rows.length} duplicate agent_contexts from secondary org were deleted (primary already had the same agent_url)`Fix 2 — migration 474: explicit transaction -- the S3 export from gate (4), not pg_dump.
+BEGIN;
+
-- ── Phase 1: drop the dependent view … ) AS run_counts ON TRUE;
+
+COMMIT;Fix 3 — S3 export script: import { writeFile } from 'node:fs/promises';
import { initializeDatabase, getPool, closeDatabase } from '../db/client.js';
import { getDatabaseConfig } from '../config.js';
async function main(): Promise<void> {
const dbConfig = getDatabaseConfig();
if (!dbConfig) { console.error('DATABASE_URL is required'); process.exit(1); }
initializeDatabase(dbConfig);
const pool = getPool();
const result = await pool.query(`
SELECT id, agent_context_id, scenario, overall_passed,
steps_passed, steps_failed, total_duration_ms,
summary, dry_run, brief, triggered_by, user_id,
steps_json, agent_profile_json, started_at, completed_at
FROM agent_test_history
WHERE user_id IS NULL
`);
const jsonl = result.rows.map((row) => JSON.stringify(row)).join('\n');
const outPath = '/app/agent_test_history_third_party.jsonl';
await writeFile(outPath, jsonl, 'utf-8');
console.log(`Exported ${result.rowCount} third-party rows to ${outPath}`);
console.log('Next: upload to S3 cold storage and commit SHA256 + S3 path to ops runbook.');
await closeDatabase();
}
main().catch((err) => { console.error(err); process.exit(1); });The full doc-comment header and usage instructions are in the prepared commit. The Session: https://claude.ai/code/session_0195XGWfSj96CJCJcxhxUX6m Generated by Claude Code |
PR 5 (final cleanup) of the #4247 unification stack. Stacked on #4268 → #4264 → #4263 → #4250.
Summary
Drops the dual-write infrastructure now that PR #4250 writes canonical, PR #4264 backfilled history, and PR #4268 derives `last_test_*` via the `agent_context_with_latest_test` view. Closes #4247.
Pre-merge gate (load-bearing — destructive migration)
DO NOT MERGE until each is satisfied:
The migration is destructive and irreversible. The S3 export from gate (4) is the recovery path.
What changes
Behavior change (named per Brian's bar)
S3 export script (operator runs before migration)
Stacked on
Merge order: #4250 → #4263 → #4264 → #4268 → this PR.
Closes #4247.
Test plan