refactor(session): drop dead task-scoped session columns (v41)
Sessions have been agent-scoped since v34, but the schema kept four
dead task-scoped columns that every session code path had to pretend
were meaningful:
- tasks.active_session_id (mirrored agents.session_id)
- tasks.session_json (superseded by task_sessions.session_params_json)
- tasks.session_display_id (superseded by task_sessions.session_display_id)
- task_sessions.task_id (always empty-string on new rows)
v41 drops all four via SQLite table rebuild — the only safe path when
multiple columns need to go in one step and indexes / FK directions
need to be preserved. `PRAGMA foreign_keys = OFF` spans the swap
window so cascade-delete does not fire mid-rebuild. The migration is
idempotent and also backfills the optional task columns
(task_type / requires_user_review / retry_count / last_failure_at /
started_at / completed_at / cancelled_at / checkout_run_id /
execution_locked_at) before rebuilding so it works whether or not
`ensureOptionalColumns` has run yet on this install.
Along with the schema change, every code path that read or wrote
those columns has been rewired to the agent-scoped equivalents:
- task-sessions-crud.ts: deleted updateTaskSession,
getTaskSession, getActiveTaskSession, updateTasksActiveSessionForAgent;
added updateSessionParams(sessionId, ...) for the worker's
finalizer. ensureAgentSession and createNewSession no longer touch
task_id.
- database-base.ts: facade drops the now-unused pass-throughs.
- snapshot.ts / task-queries.ts / tasks-status.ts / entity-crud.ts:
SELECT projections no longer pull session_json / session_display_id
/ active_session_id from tasks.
- tasks-crud.ts (TaskRow) and shared/types/records-core.ts
(TaskRecord): sessionJson / sessionDisplayId fields removed.
- TaskSessionRecord: taskId field removed.
- turn-context.ts::resolveSession: no more
updateTasksActiveSessionForAgent mirror; sessionParams read directly
from the current session via getSessionById.
- run-finished-helpers.ts::finalizeRun: stamps sessionParams via
updateSessionParams on the agent's current session, resolved through
agents.session_id.
- session-management-service.ts: rotateSession stops calling
updateTasksActiveSessionForAgent.
Test suite updated to use the new session-id API. Existing tests used
`getActiveTaskSession(taskId)` and `createNewSession({ taskId, ...})`
as probes; they now use `getSessionById(sessionId)` and the taskId-less
createNewSession input.
Tests: 603/603 green. Typecheck clean. Migration tested on fresh DB
(runs v1→v41 cleanly) and idempotent re-apply (detects absent dead
columns, skips).
This commit is contained in:
1 parent
6abc1a823f
commit
2ace9183b0
17 files changed
+270
-243
No files matched your search
@@ -116,7 +116,6 @@ describe("Edge Case: Session Rotation During Execution (D-05.3)", () => {
|
||||
|
||||
// Create a session
|
||||
const sessionId = db.createNewSession({
|
||||
taskId,
|
||||
companyId,
|
||||
agentId,
|
||||
adapterType: "gemini-cli",
|
||||
@@ -130,7 +129,7 @@ describe("Edge Case: Session Rotation During Execution (D-05.3)", () => {
|
||||
}
|
||||
|
||||
// Get the updated session from DB
|
||||
const session = db.getActiveTaskSession(taskId);
|
||||
const session = db.getSessionById(sessionId);
|
||||
expect(session).not.toBeNull();
|
||||
expect(session!.runCount).toBe(DEFAULT_THRESHOLDS.maxRuns);
|
||||
|
||||
@@ -145,7 +144,6 @@ describe("Edge Case: Session Rotation During Execution (D-05.3)", () => {
|
||||
const sessionService = createSessionManagementService({ db, logger: mockLogger });
|
||||
|
||||
const sessionId = db.createNewSession({
|
||||
taskId,
|
||||
companyId,
|
||||
agentId,
|
||||
adapterType: "gemini-cli",
|
||||
@@ -157,7 +155,7 @@ describe("Edge Case: Session Rotation During Execution (D-05.3)", () => {
|
||||
// DEFAULT_THRESHOLDS.maxTokens = 500_000 (total input + output)
|
||||
db.incrementSessionUsage(sessionId, 300000, 250000, "big-run");
|
||||
|
||||
const session = db.getActiveTaskSession(taskId);
|
||||
const session = db.getSessionById(sessionId);
|
||||
expect(session).not.toBeNull();
|
||||
const totalTokens = session!.totalInputTokens + session!.totalOutputTokens;
|
||||
expect(totalTokens).toBe(550000);
|
||||
@@ -172,7 +170,6 @@ describe("Edge Case: Session Rotation During Execution (D-05.3)", () => {
|
||||
const sessionService = createSessionManagementService({ db, logger: mockLogger });
|
||||
|
||||
const sessionId = db.createNewSession({
|
||||
taskId,
|
||||
companyId,
|
||||
agentId,
|
||||
adapterType: "gemini-cli",
|
||||
@@ -205,7 +202,7 @@ describe("Edge Case: Session Rotation During Execution (D-05.3)", () => {
|
||||
unattributedCost: false,
|
||||
});
|
||||
|
||||
const session = db.getActiveTaskSession(taskId)!;
|
||||
const session = db.getSessionById(sessionId)!;
|
||||
// generateHandoff is agent-scoped: it walks the agent's runs across
|
||||
// all tasks + taskless heartbeats, not a single task.
|
||||
const handoff = sessionService.generateHandoff(session);
|
||||
@@ -230,7 +227,6 @@ describe("Edge Case: Session Rotation During Execution (D-05.3)", () => {
|
||||
|
||||
// Create initial session
|
||||
const oldSessionId = db.createNewSession({
|
||||
taskId,
|
||||
companyId,
|
||||
agentId,
|
||||
adapterType: "gemini-cli",
|
||||
@@ -246,7 +242,6 @@ describe("Edge Case: Session Rotation During Execution (D-05.3)", () => {
|
||||
|
||||
// Create new session
|
||||
const newSessionId = db.createNewSession({
|
||||
taskId,
|
||||
companyId,
|
||||
agentId,
|
||||
adapterType: "gemini-cli",
|
||||
@@ -255,7 +250,7 @@ describe("Edge Case: Session Rotation During Execution (D-05.3)", () => {
|
||||
});
|
||||
|
||||
// Get the new active session
|
||||
const newSession = db.getActiveTaskSession(taskId);
|
||||
const newSession = db.getSessionById(newSessionId);
|
||||
expect(newSession).not.toBeNull();
|
||||
expect(newSession!.id).toBe(newSessionId);
|
||||
expect(newSession!.id).not.toBe(oldSessionId);
|
||||
@@ -271,7 +266,6 @@ describe("Edge Case: Session Rotation During Execution (D-05.3)", () => {
|
||||
const sessionService = createSessionManagementService({ db, logger: mockLogger });
|
||||
|
||||
const sessionId = db.createNewSession({
|
||||
taskId,
|
||||
companyId,
|
||||
agentId,
|
||||
adapterType: "claude-pro",
|
||||
@@ -284,7 +278,7 @@ describe("Edge Case: Session Rotation During Execution (D-05.3)", () => {
|
||||
db.incrementSessionUsage(sessionId, 30000, 20000, `run-${i}`);
|
||||
}
|
||||
|
||||
const session = db.getActiveTaskSession(taskId)!;
|
||||
const session = db.getSessionById(sessionId)!;
|
||||
// Pi-mono delegates compaction to pi-agent-core; AgentCompany still applies rotation uniformly.
|
||||
const result = sessionService.evaluateRotation(session, "claude-pro");
|
||||
expect(result.shouldRotate).toBe(true);
|
||||
@@ -296,7 +290,6 @@ describe("Edge Case: Session Rotation During Execution (D-05.3)", () => {
|
||||
const sessionService = createSessionManagementService({ db, logger: mockLogger });
|
||||
|
||||
const sessionId = db.createNewSession({
|
||||
taskId,
|
||||
companyId,
|
||||
agentId,
|
||||
adapterType: "openai-codex",
|
||||
@@ -309,7 +302,7 @@ describe("Edge Case: Session Rotation During Execution (D-05.3)", () => {
|
||||
db.incrementSessionUsage(sessionId, 30000, 20000, `run-${i}`);
|
||||
}
|
||||
|
||||
const session = db.getActiveTaskSession(taskId)!;
|
||||
const session = db.getSessionById(sessionId)!;
|
||||
// Pi-mono delegates compaction to pi-agent-core; AgentCompany still applies rotation uniformly.
|
||||
const result = sessionService.evaluateRotation(session, "openai-codex");
|
||||
expect(result.shouldRotate).toBe(true);
|
||||
@@ -322,7 +315,6 @@ describe("Edge Case: Session Rotation During Execution (D-05.3)", () => {
|
||||
|
||||
// Create session and add usage
|
||||
const sessionId = db.createNewSession({
|
||||
taskId,
|
||||
companyId,
|
||||
agentId,
|
||||
adapterType: "gemini-cli",
|
||||
@@ -352,7 +344,7 @@ describe("Edge Case: Session Rotation During Execution (D-05.3)", () => {
|
||||
});
|
||||
|
||||
// Rotate the session (archives old, creates new)
|
||||
const oldSession = db.getActiveTaskSession(taskId)!;
|
||||
const oldSession = db.getSessionById(sessionId)!;
|
||||
sessionService.rotateSession(oldSession);
|
||||
|
||||
// After rotation, the handoff should be retrievable for the next run
|
||||
|
||||
Reference in new issue
Block a user