Skip to content

fix(v5): harden roadmap sync per PR #2729 bot-review findings - #2734

Merged
namastex888 merged 1 commit into
devfrom
fix/pr-2729-review
Jul 29, 2026
Merged

namastex888 merged 1 commit into
devfrom
fix/pr-2729-review

Conversation

@namastex888

Copy link
Copy Markdown
Contributor

Verifies and fixes the bot review findings (Codex + CodeRabbit) on rolling PR #2729. Each finding was checked against the actual code; invalid ones are dispositioned in the PR #2729 review discussion.

Fixed (verified real):

  • task export/import: path-normalize before the canonical-roadmap comparison — an explicit relative .genie/roadmap.json no longer wipes local hire_roster or skips the sync baseline (Codex P1)
  • task export --write <file>: custom-file backups now carry the complete state incl. hire_roster; only the canonical path gets the roadmap slice, so backup.json → import --replace round-trips lossless (Codex P2)
  • importState: --replace wipes all tables even when only meta rows exist — stale wish_sig/backfill markers can no longer merge into the snapshot and trigger false drift (Codex P2); malformed rows that pass shape validation now rethrow as SnapshotFormatError after rollback instead of raw SQLite bind errors (CodeRabbit)
  • syncRoadmap: whole compare-and-act sequence under BEGIN IMMEDIATE — closes the TOCTOU where a task write committed between hash comparison and replace-import would be silently destroyed, and serializes concurrent syncs (git hook vs interactive command) via busy_timeout (Codex P1 + CodeRabbit major)
  • .husky/pre-commit: stages roadmap.json only when sync itself rewrote it (hash-compare before/after) — pre-existing unstaged edits are no longer absorbed into unrelated commits (Codex P1)
  • .husky/post-checkout (new): same three-way task sync after branch checkouts ($3=1 only), so the shared db stops exposing the previous branch's board (Codex P1)
  • .hermes/SOUL.md: prohibition narrowed to the obsolete top-level genie serve; genie omni serve explicitly exempt (CodeRabbit)
  • scripts/release-docs.test.ts: router metadata (agents/openai.yaml) now asserted to carry the security-sensitive bypass rule (CodeRabbit)

Regression tests added: explicit-relative-canonical-path behavior + lossless custom backup (v5-task.test.ts); metadata-only replace wipe + SnapshotFormatError rollback (task-state.test.ts).

Validation: typecheck, biome, knip, skills/wishes lint, complexity budget, hook-bundle parity all green; full bun test green in all touched areas (remaining local failures are pre-existing umask-002 / GitHub-release-asset environment issues, absent under umask 022 and green in CI).

🤖 Generated with Claude Code

- task export/import: resolve explicit paths before the canonical
  comparison, so a relative spelling of .genie/roadmap.json preserves
  local hires and records the sync baseline
- task export --write <file>: custom-file backups emit the complete
  state including hire_roster; only canonical roadmap.json gets the
  roadmap slice, keeping backup round-trips lossless
- importState: --replace wipes all tables even when only meta rows
  exist, so stale wish_sig/backfill markers cannot merge into the
  snapshot; malformed rows that pass shape validation rethrow as
  SnapshotFormatError after rollback
- syncRoadmap: compare-and-act runs under BEGIN IMMEDIATE, closing the
  window where a concurrent task write could be destroyed by a
  replace-import and serializing concurrent syncs
- pre-commit: stage roadmap.json only when sync itself rewrote it,
  never absorbing pre-existing unstaged edits
- post-checkout (new hook): run task sync after branch checkouts so the
  shared db stops exposing the previous branch's board
- .hermes/SOUL.md: narrow the obsolete-serve prohibition so it cannot
  be read as banning the supported 'genie omni serve'
- release-docs.test.ts: assert the security-sensitive bypass rule in
  router metadata too

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@gemini-code-assist

Copy link
Copy Markdown
Contributor

Caution

The consumer version of Gemini Code Assist on GitHub has been sunset. All code review activity has officially ceased.

@coderabbitai

coderabbitai Bot commented Jul 29, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 9e6840c0-74b2-4b00-bbdb-71e3258f2933

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

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.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 594a273e69

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

// machine-local worktree paths). Custom-file writes and the plain stdout
// dump stay the complete database, so a backup file round-trips lossless.
const target = opts.write ? (typeof opts.write === 'string' ? resolve(opts.write) : resolveRoadmapPath()) : null;
const canonical = target === resolveRoadmapPath();

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Treat linked-worktree roadmap paths as canonical

When this command runs inside a linked worktree and the user explicitly passes .genie/roadmap.json, resolve(opts.write) points to that worktree's tracked file while resolveRoadmapPath() deliberately points to the main checkout via the common Git directory, so canonical is false. The export then writes the complete hire_roster, including machine-local worktree paths, into a tracked roadmap; the mirrored import comparison also treats that file as a full backup and can wipe local hires with --replace. I reproduced this from a linked worktree, which is a supported Genie execution mode, so recognize the linked checkout's roadmap as canonical or reject that target.

AGENTS.md reference: AGENTS.md:L35-L35

Useful? React with 👍 / 👎.

Comment thread src/lib/v5/task-state.ts
Comment on lines +1593 to +1598
if (err instanceof SnapshotFormatError || err instanceof NonEmptyImportError) throw err;
// A malformed row that passed shape validation (roadmap.json survives git
// merges) surfaces as an opaque SQLite bind error — rethrow it in the same
// actionable class as the structural checks. The transaction rolled back.
throw new SnapshotFormatError(
`Snapshot rows could not be imported: ${err instanceof Error ? err.message : String(err)}. The database was left unchanged; re-export the snapshot or repair the malformed rows.`,

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Preserve transient database errors during import

When another process holds the SQLite write lock longer than busy_timeout, apply() throws a retryable SQLITE_BUSY, but this blanket conversion reports SnapshotFormatError and instructs the user to repair or re-export a snapshot that is not malformed. Preserve transient and operational SQLite errors here, and only translate bind or constraint failures that can actually be attributed to malformed snapshot rows.

Useful? React with 👍 / 👎.

@namastex888
namastex888 merged commit 7949faa into dev Jul 29, 2026
17 checks passed
@automagik-genie
automagik-genie deleted the fix/pr-2729-review branch September 25, 2026 04:50
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.

1 participant