Skip to content

Promote dev to stable: Genie observability resume-anchor fix - #2475

Merged
namastex888 merged 5 commits into
mainfrom
dev
May 22, 2026
Merged

namastex888 merged 5 commits into
mainfrom
dev

Conversation

@namastex888

@namastex888 namastex888 commented May 22, 2026 •

Copy link
Copy Markdown
Contributor

Promotes dev to stable after fixing Genie observability/session-linkage false degraded states.\n\nKey fix:\n- align observe health with actual resume anchors by not flagging missing_session when executors.claude_session_id exists\n- stamp ended_at for terminal executors created in terminal initial states\n- add regression coverage\n\nEvidence:\n- local pre-push checks passed\n- CI success on dev commit 38d1866\n- dev release v4.260522.8 published successfully\n\nThis should allow stable channel to advance beyond stale installer behavior once merged/released.

Summary by CodeRabbit

  • Bug Fixes

    • Fixed database restore to properly rebalance PostgreSQL identity sequences after restore operations
    • Refined missing session health flag detection logic
  • New Features

    • Executor states now automatically track completion timestamps for terminal states
  • Tests

    • Added comprehensive test coverage for database identity sequence rebalancing
    • Enhanced executor state and observability tests
  • Chores

    • Version bumped to 4.260522.8

Review Change Stack

vasconceloscezar and others added 5 commits May 22, 2026 12:22
`pg_dump --clean --if-exists` (used by `genie db backup`) drops every
IDENTITY-bearing table and recreates it via DDL — resetting the implicit
identity sequence to its initial value (1). The subsequent COPY restores
rows with their original explicit ids (1..N), but pg_dump does NOT emit
a setval() to advance the sequence past N. The next IDENTITY-generated
INSERT then collides with an existing row's PK, breaking every
PG-touching CLI command.

Observed on khal-os 2026-05-22: `_genie_migrations` had 63 rows but
`_genie_migrations_id_seq` was at 48; the first attempt to apply pending
migration 064 hit `duplicate key value violates unique constraint
"_genie_migrations_pkey"`. Every `genie ls`, `genie task list`,
`genie events` invocation failed identically — total CLI lockout until
a manual `setval()`.

Two-pronged fix:

1. **`rebalanceIdentitySequences()` in db-backup.ts**, called at the
   end of `restore()`. Walks every `attidentity` column in `public`
   via a single PL/pgSQL DO block and `setval(seq, GREATEST(MAX(col), 1),
   is_called)`. Idempotent: empty tables get `setval(1, false)` so the
   next nextval() yields 1 (canonical IDENTITY-start behavior);
   non-empty tables advance past MAX(col). Exported so operators on a
   pre-fix host can recover without re-restoring. Injectable `runner`
   seam keeps it unit-testable.

2. **Defensive setval in `runMigrations()`** (db-migrations.ts), guarded
   on `pending.length > 0` so the cost is paid only when actually about
   to INSERT. Self-heals any host that already drifted via a pre-fix
   restore, so upgrading to this version is enough — no manual SQL
   needed.

10 new tests pin the SQL shape, runner contract, error paths (non-zero
exit, null status timeout, string-vs-Buffer stderr), and the
restore-then-rebalance ordering in `restore()`.
…identity-sequences

fix(db): rebalance IDENTITY sequences after restore + defensive setval
@chatgpt-codex-connector

Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.

@coderabbitai

coderabbitai Bot commented May 22, 2026 •

Copy link
Copy Markdown

Caution

Review failed

Pull request was closed or merged during review

📝 Walkthrough

Walkthrough

This PR updates the genie package to version 4.260522.8 across all manifests, refines the session health flag condition to require absence of both linkage and anchor fields, adds database IDENTITY sequence rebalancing to compensate for pg_dump desynchronization, and ensures executor records properly set ended_at timestamps for terminal states on creation.

Changes

Version and Manifest Updates

Layer / File(s) Summary
Version bump across manifests
.claude-plugin/marketplace.json, package.json, plugins/genie/.claude-plugin/plugin.json, plugins/genie/package.json
All version fields updated from 4.260522.6 to 4.260522.8.

Session Health Flag and Executor Lifecycle

Layer / File(s) Summary
Health flag refinement: missing_session condition
src/lib/agent-observability.ts, src/lib/agent-observability.test.ts
missing_session flag now requires both sessionId and claudeSessionId to be absent; test cases updated to verify the condition fires only when session anchoring is completely unavailable, with a new test confirming the flag does not fire for resume-ready terminated executors.
Executor creation: set ended_at for terminal states
src/lib/executor-registry.ts, src/lib/executor-registry-pure.test.ts
New initialEndedAtForState() helper determines whether to populate ended_at based on executor state; createExecutor and createAndLinkExecutor now include ended_at in INSERT statements, with tests validating timestamp initialization for both terminal and live states.

Database Recovery and Migrations

Layer / File(s) Summary
Database recovery: IDENTITY sequence rebalancing
src/lib/db-backup.ts, src/lib/db-backup.test.ts
Exported buildIdentityRebalanceSql() generates a PL/pgSQL DO block that resets PostgreSQL IDENTITY sequences to match row counts via setval(); rebalanceIdentitySequences() executes the block via psql (or injected runner); restore() now calls rebalancing after successful dump replay to prevent sequence desynchronization. Comprehensive tests cover SQL generation, execution handling, error cases, and integration order.
Migration safety: sequence rebalancing before insert
src/lib/db-migrations.ts
runMigrations adds defensive setval() for the _genie_migrations_id_seq sequence before inserting new records, and short-circuits with empty result when no migrations are pending.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

  • automagik-dev/genie#1159: Updates version fields in the same manifest files, but different feature implementation (buildResumeParams vs. database recovery logic).
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 75.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title directly addresses the main purpose of the PR: promoting dev to stable after fixing observability/session-linkage issues, which is confirmed by the PR objectives.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch dev

Warning

There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure.

🔧 ESLint

If the error stems from missing dependencies, add them to the package.json file. For unrecoverable errors (e.g., due to private dependencies), disable the tool in the CodeRabbit configuration.

ESLint skipped: no ESLint configuration detected in root package.json. To enable, add eslint to devDependencies.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@namastex888
namastex888 merged commit fceb5be into main May 22, 2026
28 of 31 checks passed

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request includes version updates across several configuration files and introduces a mechanism to rebalance PostgreSQL identity sequences after a database restore to prevent primary key collisions. It also updates agent observability logic to consider claudeSessionId when determining session health and modifies the executor registry to record ended_at timestamps for terminal states. Feedback was provided regarding the use of ESM-compatible directory variables in tests and improving the robustness of SQL identifier quoting in the rebalance logic.

Comment thread src/lib/db-backup.test.ts

describe('restore() rebalance wiring (source-shape lock)', () => {
test('restore() calls rebalanceIdentitySequences after the psql pipe', () => {
const source = readFileSync(join(__dirname, 'db-backup.ts'), 'utf-8');

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

__dirname is not available in ES modules, which this project uses (as indicated by "type": "module" in package.json). Using it will cause a runtime error in a pure ESM environment. Use import.meta.dir instead, which is the idiomatic equivalent in Bun and ESM.

Suggested change
const source = readFileSync(join(__dirname, 'db-backup.ts'), 'utf-8');
const source = readFileSync(join(import.meta.dir, 'db-backup.ts'), 'utf-8');

Comment thread src/lib/db-backup.ts
Comment on lines +284 to +288
'SELECT setval(pg_get_serial_sequence(%L, %L), GREATEST(COALESCE((SELECT MAX(%I) FROM %I.%I), 0), 1), COALESCE((SELECT MAX(%I) FROM %I.%I), 0) > 0)',
r.sch || '.' || r.tbl, r.col,
r.col, r.sch, r.tbl,
r.col, r.sch, r.tbl
);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The current concatenation r.sch || '.' || r.tbl is not robust against schema or table names that contain special characters or dots (e.g., a schema named my.schema). While unlikely in the current database structure, it is best practice to use quote_ident when constructing qualified names for functions like pg_get_serial_sequence to ensure they are correctly parsed by PostgreSQL.

Suggested change
'SELECT setval(pg_get_serial_sequence(%L, %L), GREATEST(COALESCE((SELECT MAX(%I) FROM %I.%I), 0), 1), COALESCE((SELECT MAX(%I) FROM %I.%I), 0) > 0)',
r.sch || '.' || r.tbl, r.col,
r.col, r.sch, r.tbl,
r.col, r.sch, r.tbl
);
EXECUTE format(
'SELECT setval(pg_get_serial_sequence(quote_ident(%L) || ''.'' || quote_ident(%L), %L), GREATEST(COALESCE((SELECT MAX(%I) FROM %I.%I), 0), 1), COALESCE((SELECT MAX(%I) FROM %I.%I), 0) > 0)',
r.sch, r.tbl, r.col,
r.col, r.sch, r.tbl,
r.col, r.sch, r.tbl
);

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants