Two bugs that cause plumb sync to silently fail
Context
I'm using plumb alongside spec-kit for a spec-driven development workflow. spec-kit generates feature specs under a specs/ directory (e.g., specs/001-feature/spec.md, specs/002-feature/spec.md), so the natural plumb config is:
{
"spec_paths": ["specs/"]
}
This triggers both bugs below.
Bug 1: Directory spec_paths skipped in sync_decisions (PR #2)
When spec_paths contains a directory (e.g., "specs/"), sync_decisions() in sync.py and _run_modify() in cli.py skip it because spec_path.is_file() returns False. Meanwhile, parse_spec_files() in the same file handles directories correctly via rglob("*.md").
Impact: plumb sync marks decisions as synced but never updates any spec files. The user sees "0 spec sections updated" with no error.
Fix: PR #2 applies the same directory resolution pattern to both functions.
Bug 2: read_all_decisions() fails silently with DuckDB <1.0
decision_log.py line 161 uses format='newline_delimited' in the DuckDB query:
FROM read_json_auto('{glob_pattern}', format='newline_delimited')
DuckDB versions before ~1.0 don't support the format parameter (the parameter was called json_format in older versions, or didn't exist). The query fails, the exception is caught on line 173 (except Exception: return []), and read_all_decisions() silently returns an empty list.
Impact: All commands that use read_all_decisions() — including plumb sync, plumb status, and plumb coverage — see zero decisions. plumb sync reports "No unsynced decisions found."
Workaround: pip install --upgrade duckdb (upgrade to ≥1.0). I upgraded from 0.7.1 → 1.5.0.
Suggested fix: Either pin duckdb>=1.0 in setup.cfg/pyproject.toml, or add a fallback query without the format parameter for older versions. Also consider not silently swallowing the exception — at minimum log it so users can diagnose the failure.
Combined effect
With both bugs present, plumb sync appears to work but does nothing:
- Bug 2 makes
read_all_decisions() return [] → "No unsynced decisions"
- Even after fixing DuckDB, Bug 1 makes the spec file loop skip all files → "0 spec sections updated" but decisions get marked as synced
Environment: macOS, Python 3.11, plumb 0.2.4, DuckDB 0.7.1 (before upgrade)
Two bugs that cause
plumb syncto silently failContext
I'm using plumb alongside spec-kit for a spec-driven development workflow. spec-kit generates feature specs under a
specs/directory (e.g.,specs/001-feature/spec.md,specs/002-feature/spec.md), so the natural plumb config is:{ "spec_paths": ["specs/"] }This triggers both bugs below.
Bug 1: Directory spec_paths skipped in sync_decisions (PR #2)
When
spec_pathscontains a directory (e.g.,"specs/"),sync_decisions()insync.pyand_run_modify()incli.pyskip it becausespec_path.is_file()returnsFalse. Meanwhile,parse_spec_files()in the same file handles directories correctly viarglob("*.md").Impact:
plumb syncmarks decisions as synced but never updates any spec files. The user sees "0 spec sections updated" with no error.Fix: PR #2 applies the same directory resolution pattern to both functions.
Bug 2:
read_all_decisions()fails silently with DuckDB <1.0decision_log.pyline 161 usesformat='newline_delimited'in the DuckDB query:DuckDB versions before ~1.0 don't support the
formatparameter (the parameter was calledjson_formatin older versions, or didn't exist). The query fails, the exception is caught on line 173 (except Exception: return []), andread_all_decisions()silently returns an empty list.Impact: All commands that use
read_all_decisions()— includingplumb sync,plumb status, andplumb coverage— see zero decisions.plumb syncreports "No unsynced decisions found."Workaround:
pip install --upgrade duckdb(upgrade to ≥1.0). I upgraded from 0.7.1 → 1.5.0.Suggested fix: Either pin
duckdb>=1.0insetup.cfg/pyproject.toml, or add a fallback query without theformatparameter for older versions. Also consider not silently swallowing the exception — at minimum log it so users can diagnose the failure.Combined effect
With both bugs present,
plumb syncappears to work but does nothing:read_all_decisions()return[]→ "No unsynced decisions"Environment: macOS, Python 3.11, plumb 0.2.4, DuckDB 0.7.1 (before upgrade)