Skip to content

Markdown Kanban Mode#508

Open
FedorenkoCodes wants to merge 13 commits into
morapelker:mainfrom
FedorenkoCodes:codex/markdown-kanban-mode-spec
Open

Markdown Kanban Mode#508
FedorenkoCodes wants to merge 13 commits into
morapelker:mainfrom
FedorenkoCodes:codex/markdown-kanban-mode-spec

Conversation

@FedorenkoCodes

@FedorenkoCodes FedorenkoCodes commented Jun 2, 2026

Copy link
Copy Markdown
Contributor

Description

Adds Markdown Kanban Mode: an opt-in, per-project Kanban storage mode where cards are stored as markdown files in user-configured folders instead of the internal SQLite ticket table.

This version is rebased onto upstream’s RPC/API architecture. Kanban ticket, dependency, config, diagnostics, and watcher operations now route through project-aware RPC/API methods rather than the old Electron preload/IPC integration.

Related Issue

N/A

Type of Change

  • 🐛 Bug fix (non-breaking change which fixes an issue)
  • ✨ New feature (non-breaking change which adds functionality)
  • 💥 Breaking change (fix or feature that would cause existing functionality to not work as expected)
  • 📝 Documentation update
  • 🎨 UI/UX improvement
  • ⚡ Performance improvement
  • ♻️ Code refactoring
  • 🧪 Test improvement
  • 🔧 Configuration change
  • 📦 Dependency update

Changes Made

  • Added project-scoped Kanban storage routing with support for both internal SQLite-backed boards and markdown-file-backed boards.
  • Added markdown card parsing/writing, YAML frontmatter handling, diagnostics for invalid/duplicate cards, duplicate-safe renderer identity, and SQLite-backed runtime state for session/worktree/private card data.
  • Added Markdown Kanban filesystem watching for visible markdown board scopes, with project-scoped watcher lifecycle handling and self-write suppression.
  • Added Project Settings UI for selecting Kanban storage mode, configuring single-folder or status-folder layouts, creating missing folders, and selecting folders through the native picker.
  • Added RPC/API methods for Kanban config, diagnostics, watcher lifecycle, project-aware ticket mutations, and project-aware dependency mutations.
  • Updated board import/export, dependency handling, assistant flows, pinned/connection board identity, and tests for project-scoped ticket references.
  • Preserved internal Kanban behavior for existing internal-mode projects.

Screenshots

Screenshots (if applicable) Screenshot 2026-06-02 at 21 53 41 Screenshot 2026-06-02 at 21 54 01 Screenshot 2026-06-02 at 21 57 01 Screenshot 2026-06-02 at 22 02 37 Screenshot 2026-06-02 at 21 59 03

Testing

Test Configuration

  • OS: macOS 26.5
  • Node Version: v25.8.1
  • Test Type: Targeted Vitest / RPC / Renderer / Backend

Test Steps

  1. Ran targeted Markdown Kanban, RPC/API, Project Settings, Board Assistant, identity, watcher, and worktree picker tests:
    pnpm exec vitest run src/renderer/src/api/__tests__/kanban-api.test.ts src/server/__tests__/kanban-rpc.mock-provider.test.ts src/renderer/src/components/projects/ProjectSettingsDialog.test.tsx test/kanban/markdown-diagnostics-cache.test.ts test/kanban/markdown-adoption-repair.test.ts test/kanban/markdown-kanban-watcher.test.ts test/kanban/markdown-kanban-watcher-hook.test.tsx test/kanban/internal-dependency-routing.test.ts test/kanban/duplicate-card-identity.test.tsx test/kanban/board-assistant-create-navigation.test.tsx test/kanban/session-9/worktree-picker-modal.test.tsx src/renderer/src/components/kanban/KanbanTicketModal.handoff.test.tsx src/renderer/src/components/kanban/WorktreePickerModal.claude-cli.test.tsx
  2. Ran feature-owned TypeScript checks by filtering tsconfig.web and tsconfig.node output to the Markdown/Kanban/RPC files touched by this PR.
  3. Scanned for conflict markers and obsolete old Kanban IPC references.

Test Results

  • All existing tests pass
  • New tests added (if applicable)
  • Manual testing completed

Targeted test result: 13 test files passed, 224 tests passed.

Feature-owned TypeScript filters are clean for the Markdown Kanban/RPC/API files. Full workspace typecheck still fails on existing unrelated repo-wide issues outside this PR surface.

Checklist

  • My code follows the project's code style
  • I have run pnpm lint and fixed any issues
  • I have run pnpm format to format my code
  • I have run pnpm test and all tests pass
  • I have added tests that prove my fix/feature works
  • I have updated the documentation (if needed)
  • I have added comments to complex code sections
  • I have checked for any console errors
  • I have tested on macOS (required)
  • I have updated documentation (for significant changes)

Performance Impact

  • No performance impact
  • Improves performance
  • May affect performance (please explain)

Markdown mode adds filesystem scans and folder watchers for configured card folders. Watchers are scoped to visible markdown boards, and internal-mode projects no-op through the watcher APIs, so existing internal Kanban boards should not take on markdown folder scanning/watching work.

Breaking Changes

  • No breaking changes

Kanban internals are now project-scoped through RPC/API calls, but this is not intended to be a user-facing breaking change.

Additional Notes

Markdown Kanban Mode is opt-in per project and mutually exclusive with the existing internal storage mode. This PR does not add automatic migration from populated internal boards to markdown files.

Invalid or duplicate markdown cards are surfaced through diagnostics/placeholders instead of being silently ignored. Local runtime state such as sessions, worktrees, notes, attachments, plan-ready state, and token counts stays in Hive storage rather than being written to markdown files.

Previous review feedback is addressed, including markdown dependency cleanup on delete/archive/import, aggregate simple-mode drop behavior, project-scoped dependency cleanup, partial Board Assistant draft failures, and Project Settings partial-save behavior.

Post-Merge Tasks

  • Update documentation site
  • Notify users of breaking changes
  • Update README examples
  • Other:

@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: 89ee995ba9

ℹ️ About Codex in GitHub

Codex has been enabled to automatically 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 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment thread src/main/services/kanban-backend.ts Outdated
@greptile-apps

greptile-apps Bot commented Jun 2, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR adds an opt-in per-project Markdown Kanban mode where cards are stored as .md files with YAML frontmatter instead of in SQLite, rebased onto the current RPC/API architecture.

  • Introduces MarkdownKanbanBackend (2300 lines) handling card CRUD, dependency management, batch creation, layout migration, and adoption-repair for pre-existing markdown files; a runtime SQLite table (markdown_kanban_card_state) stores session/worktree/note/token data that is intentionally kept out of markdown files.
  • Adds a chokidar-based file watcher with ref-counting, debounce, and self-write suppression; all existing internal-mode projects no-op through the watcher APIs.
  • Extends Project Settings with mode/folder configuration UI and routes all kanban RPC calls through a new getKanbanBackendForProject dispatcher that selects either the internal or markdown backend per project.

Confidence Score: 4/5

Safe to merge with the understanding that the kanban config dialog can briefly show settings from a previously-opened project if the user opens and closes dialogs quickly before the RPC resolves.

All six issues flagged in the prior review round have been addressed: the duplicate isMarkdownCandidate declaration is gone, setSelectedTicketId is typed null-only, archiveAllDone now takes a single index snapshot, the layout migration has proper per-iteration rollback, non-kanban project settings are saved before the kanban mode-change call, and the migrateMarkdownLayout atomicity gap has a full rollback path. The one remaining open concern is that the kanbanApi.config.get promise in ProjectSettingsDialog has no cancellation guard while the sibling detectSetupSuggestions call does, meaning a slow response for project A can overwrite folder-path state after the user has switched to project B's dialog.

src/renderer/src/components/projects/ProjectSettingsDialog.tsx — the kanban config fetch (lines 111-134) does not participate in the effect's cancellation flag.

Important Files Changed

Filename Overview
src/main/services/kanban-backend.ts New 2323-line file implementing InternalKanbanBackend and MarkdownKanbanBackend. Previously-flagged issues (isMarkdownCandidate duplicate, archiveAllDone O(N) scans, non-atomic migration) are resolved. In create(), two reloadIndex() calls occur sequentially (once in assertCardIdAvailable, again in nextSortOrder via list()), but this is a P2 efficiency concern, not a correctness bug.
src/main/services/markdown-kanban-watcher.ts New file watcher with ref-counting, debouncing (300ms), self-write suppression (2s), and serialized per-project watch operations. Suppression is applied after writeMarkdownFile completes, which is safe given chokidar's 150ms awaitWriteFinish threshold.
src/renderer/src/components/projects/ProjectSettingsDialog.tsx Adds Kanban mode/folder UI. Non-kanban settings are now saved first (addressing previous feedback). The kanbanApi.config.get call still lacks the cancelled guard present on detectSetupSuggestions, leaving a stale-response window when the dialog is closed and reopened quickly for a different project.
src/server/rpc/domains/kanban.ts Large update adding project-scoped routing, new config/diagnostics/watcher RPC handlers, and Zod schemas for all new parameters. Router handlers correctly extract projectId and route to the right backend instance.
src/main/db/schema.ts Schema version bumped to 35; adds kanban_storage_mode/kanban_markdown_config columns to projects and creates markdown_kanban_card_state table with correct indexes and FK constraints.
src/renderer/src/api/kanban-api.ts Updated API client adding projectId to all ticket/dependency calls. ticket.create accepts _projectId but intentionally ignores it; all other methods send projectId explicitly — a minor API surface inconsistency.
src/renderer/src/stores/useKanbanStore.ts Store updated with markdown diagnostics/placeholders, setSelectedTicketId narrowed to null-only (resolving previous type complaint), and new setSelectedTicketRef for opening tickets by reference.
src/renderer/src/hooks/useMarkdownKanbanWatcher.ts New hook managing per-project watcher lifecycle with ref-counting and cleanup on unmount. Uses a stable watchedKey to avoid spurious effect re-runs.

Reviews (19): Last reviewed commit: "Address feedback again" | Re-trigger Greptile

Comment thread src/main/services/kanban-backend.ts Outdated
Comment thread src/renderer/src/stores/useKanbanStore.ts Outdated
Comment thread src/main/services/kanban-backend.ts

@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: f077959b07

ℹ️ About Codex in GitHub

Codex has been enabled to automatically 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 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment thread src/renderer/src/components/kanban/KanbanColumn.tsx Outdated

@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: e37ad255a1

ℹ️ About Codex in GitHub

Codex has been enabled to automatically 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 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment thread src/main/services/kanban-backend.ts

@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: cb95c23b5a

ℹ️ About Codex in GitHub

Codex has been enabled to automatically 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 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment thread src/main/services/kanban-backend.ts
Comment thread src/renderer/src/components/projects/ProjectSettingsDialog.tsx

@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: c5aa09e419

ℹ️ About Codex in GitHub

Codex has been enabled to automatically 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 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment thread src/renderer/src/stores/useBoardChatStore.ts Outdated
@morapelker

Copy link
Copy Markdown
Owner

this is a pretty big PR. Im in the middle of the whole ipc -> http migration
will take a look after

@FedorenkoCodes

Copy link
Copy Markdown
Contributor Author

this is a pretty big PR. Im in the middle of the whole ipc -> http migration will take a look after

I can imagine.

I'd like to add the actual migration from "internal" tickets into the markdown files (and vice versa), as a second pr. If you like the direction of course.

The greptile says that layout migration silently skips invalid markdown files - I can address that in this second pr as well.

@morapelker

Copy link
Copy Markdown
Owner

i like the direction i think it can be really cool and would allow more long running agents to run by creating boards through managing files rather than through a specialized tool controlling the board with customized commands like now. it can open doors to orchestrator agents as well, managing tickets moving them between statuses etc.

@morapelker

Copy link
Copy Markdown
Owner

We need to do the necessary adaptions to this pr so that it merges
Since many things changed in the past week including basically the entire architecture - there are probably a lot of merge conflicts

@FedorenkoCodes FedorenkoCodes force-pushed the codex/markdown-kanban-mode-spec branch from c8fbac2 to bc86ea8 Compare June 12, 2026 18:01

@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: bc86ea8210

ℹ️ About Codex in GitHub

Codex has been enabled to automatically 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 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment thread src/renderer/src/hooks/useMarkdownKanbanWatcher.ts

@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: 4aa7e721a8

ℹ️ About Codex in GitHub

Codex has been enabled to automatically 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 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment thread src/renderer/src/components/kanban/KanbanColumn.tsx Outdated

@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: 68a74ad635

ℹ️ About Codex in GitHub

Codex has been enabled to automatically 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 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment thread src/renderer/src/components/kanban/KanbanBoard.tsx
@FedorenkoCodes

Copy link
Copy Markdown
Contributor Author

@morapelker I think it's ready

@morapelker

Copy link
Copy Markdown
Owner

ive got a few comments from claude, can you investigate/check if theyre valid/fix whatever he mentions?
especially the correctness section

🔴 Correctness

  1. Markdown watcher events never reach the renderer — auto-reload silently broken
    src/main/services/markdown-kanban-watcher.ts:262
    The watcher is started from the kanban.watch.start RPC handler (src/server/rpc/domains/kanban.ts:799), which runs in the spawned server process. On a file change, flushChange calls publishDesktopBackendEvent(...), but in the server process getCurrentBackend() is null (setCurrentBackend is only called in main's backend-manager.ts), so it returns false and the event is dropped. The renderer's kanbanApi.watch.onChanged never fires, so the board does not auto-reload on external markdown edits — the whole point of the watcher. Fix mirrors git/worktree events, which inject eventBus.publish in server.ts:52-67; the watcher uses none. (This matches your saved [event-publishing-process-boundary] note.)

  2. plan_ready stuck on after resuming work from review
    src/renderer/src/stores/useKanbanStore.ts:866
    The old session_working handler reset plan_ready: false when a plan-mode ticket resumed work (review→in_progress). The new handler only moves the column and drops that reset. A ticket actively being worked keeps plan_ready=true, so the "plan ready" badge/affordances stay stuck on. Sibling handlers (session_planning, implement, mode_change) still reset it, confirming this is an unintended regression, not a design change.

  3. Debounced flush can publish a change event after the watch is stopped
    src/main/services/markdown-kanban-watcher.ts:262
    closeEntry clears a pending debounce timer, but if the timer already fired, flushChange publishes via an async import().then(...) that resolves on a later tick. flushChange never re-checks watchers.has(projectId) before publishing, so stopping a watch (e.g. user switches the project back to internal storage mid-debounce) can still emit MARKDOWN_KANBAN_CHANGED and trigger a spurious reload.

  4. review column cards are written into the in_progress folder
    src/main/services/kanban-markdown-paths.ts:107
    VALID_COLUMNS includes 'review', but ensureFolder maps done→done, todo→todo, and everything else (including review) → in_progress. The status-folders layout defines no review folder. So a review card lives in the in-progress folder while its frontmatter says column: review — the folder/frontmatter round-trip is inconsistent, and any folder-authoritative logic (layout migration, external tooling) disagrees with frontmatter. The mapping is also duplicated in planSingleFolderToStatusFolders (kanban-backend.ts:1665).

  5. addDependency silently drops links when a ticket isn't loaded in the store
    src/renderer/src/stores/useKanbanStore.ts:868
    The new code calls findTicketByRef (in-memory tickets Map) on both refs and returns {success:false} if either is missing — previously it always issued the kanban.dependency.add RPC. The backend already validates existence authoritatively, so this is a redundant client-side narrowing that rejects valid cases when the target's project slice hasn't loaded yet. (PLAUSIBLE — the common drag-to-link UI path has both tickets rendered, but lazy/aggregate-board paths can hit it.)


🟡 Efficiency / Quality

  1. list() re-reads and re-parses every card file from disk on every call
    src/main/services/kanban-backend.ts:469
    MarkdownKanbanBackend.list() → reloadIndex() does a full readdir + stat + readFile + YAML parse of every card on each board load and each watcher-triggered reload. A 200-card board re-reads 200 files per refresh; editing one card rescans the whole folder (O(n) for an O(1) change). Consider an mtime-keyed cache invalidated per changed path.

  2. Column fallback reintroduces the cross-column duplicate-key bug
    src/renderer/src/components/kanban/KanbanColumn.tsx:206
    When activeCardIdentityKeys props aren't passed, KanbanColumn falls back to cardOccurrenceKeys(tickets, markdownDiagnostics), allocating a fresh per-column occurrence map starting from 0 — exactly what commit "Share duplicate occurrence counts across columns" fixed at the board level. Duplicate-id cards in different columns can collide on the same React key (flicker, lost drag state). The fallback also recomputes an O(tickets×diagnostics) map every render.

  3. Self-write suppression is a fixed 750ms wall-clock timer, not path/content tracking
    src/main/services/markdown-kanban-watcher.ts:18
    suppressMarkdownKanbanWatch blanket-ignores all events for a project for 750ms. On a slow disk the self-write echo can arrive after the window (spurious reload loop); a genuine external edit within 750ms of any app write is silently dropped (stale board). Batch creates (N files over time) are especially exposed. Tracking the actual written paths/hashes would be robust.

  4. Frontmatter field set hand-maintained in four parallel places
    src/main/services/kanban-backend.ts:40
    HIVE_FRONTMATTER_FIELDS, publicFieldsFromCreate (~1956), validateKnownFrontmatter (~1815), and the zod schemas in kanban.ts (~191/233) each enumerate ticket fields independently as runtime string sets the compiler can't cross-check. Add a field and miss one → it's silently stripped by mergeFrontmatter, rejected by .strict(), or written-but-unvalidated.

  5. Duplicated slugify / uniquePath helpers
    src/main/services/kanban-backend.ts:2041,2051
    New slugify() and uniquePath() re-implement existing helpers (canonicalizeTicketTitle in shared/types/branch-utils.ts; slug()/uniquePath() in server/rpc/domains/teleport-ops.ts) with divergent rules (length caps 64 vs 32, async stat vs existsSync, retry limits 1000 vs 100). A future slug-safety fix (e.g. Windows-reserved names) must be applied in multiple places or filenames/worktree names diverge. The watcher also uses a hand-rolled no-op log stub instead of the shared createLogger every sibling watcher uses, making all its logging dead.


Verdict: Finding #1 should block — the watcher's auto-reload doesn't work cross-process. #2 and #4 are concrete user-visible regressions. The rest are real but lower-severity. Note nextSortOrder excluding archived cards (kanban-backend.ts:1519) creates real sort_order collisions but is currently harmless since archived view sorts by archived_at — worth a comment but not a fix.

@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: 961d9e0881

ℹ️ About Codex in GitHub

Codex has been enabled to automatically 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 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment thread src/renderer/src/components/kanban/KanbanTicketModal.tsx Outdated
Comment thread src/server/server.ts

@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: 795abe6ec0

ℹ️ About Codex in GitHub

Codex has been enabled to automatically 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 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment thread src/main/services/kanban-backend.ts
@FedorenkoCodes

Copy link
Copy Markdown
Contributor Author

@morapelker Addressed findings 1, 2, 3, 4, 5, 7, and 8. That includes watcher event delivery across the server/main boundary, watcher stop-race guarding, plan_ready reset on resumed work, a dedicated review status folder, backend-authoritative dependency add behavior, duplicate fallback identity hardening, and path-scoped self-write suppression.

Leaving 6, 9, and 10 out of this PR for now:

  • 6: full mtime/content caching is valid but larger and higher-risk because it touches index invalidation, diagnostics, duplicate handling, and watcher semantics.
  • 9: frontmatter field-list consolidation is a maintainability cleanup, not a current user-facing bug.
  • 10: slug/uniquePath consolidation is also cleanup and can be handled separately without blocking Markdown Kanban readiness.

@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: a0e372abef

ℹ️ About Codex in GitHub

Codex has been enabled to automatically 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 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment thread src/server/rpc/domains/kanban.ts Outdated
Comment thread src/main/services/kanban-backend.ts Outdated
Comment thread src/renderer/src/components/projects/ProjectSettingsDialog.tsx
…-rpc-rebase

# Conflicts:
#	src/renderer/src/api/kanban-api.ts
#	src/renderer/src/components/kanban/KanbanTicketCard.tsx
#	src/server/rpc/domains/kanban.ts

@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: 93af1b64b7

ℹ️ About Codex in GitHub

Codex has been enabled to automatically 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 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment thread src/server/rpc/domains/kanban.ts Outdated
Comment thread src/main/services/kanban-backend.ts Outdated

@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: 987b5b0da3

ℹ️ About Codex in GitHub

Codex has been enabled to automatically 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 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment thread src/main/services/kanban-backend.ts
Comment thread src/main/services/kanban-backend.ts
@morapelker

Copy link
Copy Markdown
Owner

There are quite alot of "Correctness" review items claude is mentioning.
Code Review: pembroke-corgi (markdown-kanban feature)

A large feature (~9.8k lines) adding markdown-file-backed kanban boards alongside the existing DB-backed boards. The core architecture is sound — a polymorphic KanbanBackend interface dispatched by getKanbanBackendForProject, rather than scattered if (isMarkdown) branches. But the project-scoping refactor and a file rewrite introduced several confirmed regressions.

🔴 Correctness bugs

  1. Merge-conflict worktree silently lost — key mismatch (useWorktreeStatusStore.ts:416 / readers in KanbanTicketCard.tsx:240, KanbanTicketModal.tsx:489)
    The PR migrated readers of mergeConflictWorktreeByTicket to state.mergeConflictWorktreeByTicket[ticketKey(project_id, id)], but the writer (MergeOnDoneDialog.tsx:351 → setMergeConflictWorktreeForTicket) still stores under the raw ticket.id. "abc" !== "proj:abc", so every lookup misses and the card/modal silently falls back to ticket.worktree_id, pointing the conflict-fix flow at the wrong worktree. Fix: key the writer with ticketKey(projectId, id) too (projectId is available on pendingDoneMove).

  2. Permanent runtime-state loss on a transient YAML error (kanban-backend.ts:1536, cleanupRuntimeRows)
    A YAML parse error throws a plain Error, so reloadIndex records a diagnostic with ticketId: null (line 1263). The broken card is then absent from both cardsById and blockedSeenIds (which only collects diagnostics with a non-null ticketId, line 1304). cleanupRuntimeRows marks the runtime row orphaned_at on the first reload and deletes it on the second — and list()/reloadIndex runs on every watcher event, tab switch, and diagnostics poll. Once deleted, current_session_id, worktree_id, total_tokens, note, plan_ready, and pending_launch_config are gone for good (the markdown file never stored them). A momentary broken-frontmatter window destroys the session link. Fix: key the orphan grace on file path for parse-error diagnostics, or skip cleanup while blocking parse errors exist.

  3. Import/export dialog RPC hangs forever + listener leak (kanban.ts:859 and :904)
    The PR deleted the 5s setTimeout+clearTimeout from requestKanbanOpenBoardImportFileDialog and requestKanbanSaveBoardExportDialog. cleanup() (which calls process.off('message', onMessage)) now only runs via finish(), which only fires when a reply arrives or send itself errors. If the desktop main process never replies (window closed mid-dialog, handler error before reply), the Promise never settles and the process.on('message', …) listener accumulates on every call. Fix: restore the timeout-based rejection + cleanup.

  4. Cross-project move to/from a markdown board drops all dependencies (kanban-backend.ts:1623, moveKanbanTicketToProject)
    The internal→internal fast path handles dependencies, but the generic branch (used whenever either side is markdown) does create+update+delete copying title/description/attachments/etc. and never reads getDependenciesForProject on the source nor re-creates blocker edges on the destination. Deleting the source then removes them. Moving a ticket silently loses all blocker/dependent relationships, no error surfaced. Fix: copy dependency edges in the generic branch.

  5. addDependency throws instead of returning {success:false} (kanban-backend.ts:883)
    requireMutableCardFromIndex (line 1404) throws ('Ticket does not exist' or the duplicate-id message) on a missing/duplicate card — it never returns null. So the guard if (!dependent || !blocker) return {success:false, …} on line 883 is dead code. When a card was deleted on disk between read and wiring a dependency, the UI gets an uncaught rejection instead of the intended graceful failure.

  6. removeDependency silently skips the RPC (useKanbanStore.ts:825)
    The new if (!dependentTicket) return early-return fires whenever the dependent ticket isn't in the loaded local store (archived, or board not loaded), so kanban.dependency.remove is never sent — the dependency persists on disk/DB while the UI action appears to do nothing. The old code issued the RPC unconditionally. Fix: use dependent.projectId (already on the TicketRef) for the call and drop the early return.

  7. Read paths mutate files on disk (kanban-backend.ts:1334, parseCard)
    When an adopted/hand-authored card has no id, parseCard generates one and calls rewriteCard — a file write. parseCard runs from reloadIndex, which is hit by pure reads (list, getDiagnostics polling, getBlockers). On a read-only checkout the write throws and demotes the card to a parse_error; concurrent reloads race to assign ids. Fix: assign ids during an explicit adopt/repair step, not on every read.

  8. New watcher missing useFsEvents: false — reintroduces the macOS quit-hang (markdown-kanban-watcher.ts:202)
    Every other chokidar watcher in the repo (branch-watcher.ts, worktree-watcher.ts, file-tree-watcher.ts) sets useFsEvents: false precisely to avoid the documented fsevents finalizer deadlock on app quit. This new watcher omits it, so on macOS it falls back to native fsevents and any project in markdown mode can reintroduce the "must Force Quit on exit" hang. Fix: add useFsEvents: false (ideally via a shared options helper).

🟠 Quality / altitude

  1. Followups from the ticket modal lost telemetry, handoff, and auto-pin (KanbanTicketModal.tsx)
    The rewrite of sendFollowupToSession dropped startHivePromptTelemetry, registerHivePromptHandoff, and void autoPinBaseWorktree(...) (and the imports). Every other send path (WorktreePickerModal, SessionView, auto-launch…) still calls these. The verifier noted the file looks wholesale reset to an older revision during the rebase — worth confirming this is intentional and not an accidental regression of enterprise metrics/handoff chains.

  2. Watcher errors silently discarded (markdown-kanban-watcher.ts:12) — const log = { info: () => undefined, error: () => undefined } is a hard-coded no-op stub, so the watcher.on('error', …) handler throws away EMFILE/permission/deleted-folder failures. "Markdown board not refreshing" bug reports will have zero diagnostic trail. Wire in the real logger the other watchers use.

Also worth a cleanup pass (not blocking): the new runtime-state table uses 11 inline raw-SQL statements via getRawDb() bypassing the typed Database class every other table uses (kanban-backend.ts:1457); wouldCreateDependencyCycle and slugify duplicate existing helpers; and each markdown mutation triggers 2–4 full-directory reloads (O(cards) disk I/O per drag/reorder).


The four I'd treat as must-fix before merge: #1 (wrong worktree), #2 (data loss), #3 (hang), and #4 (lost dependencies). #9 needs a decision on whether the file reset was intentional.

@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: ce61a7b2c8

ℹ️ About Codex in GitHub

Codex has been enabled to automatically 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 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment thread src/main/services/kanban-backend.ts Outdated
Comment thread src/main/services/kanban-backend.ts

@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: c1c8470cae

ℹ️ About Codex in GitHub

Codex has been enabled to automatically 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 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment thread src/renderer/src/stores/useKanbanStore.ts Outdated
Comment thread src/main/services/kanban-backend.ts
@FedorenkoCodes

Copy link
Copy Markdown
Contributor Author

@morapelker I've addressed all the findings of Claude, except for #3 Restore import/export dialog timeout - the concern is theoretically valid if main never replies, but restoring a 5s timeout is wrong for native dialogs; and #4 Cross-project move drops dependencies - factually true, but not necessarily a bug, as accepted move semantics intentionally clear dependency links when moving projects.

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.

2 participants