taskwrite.py: missing-board error path (uninitialized repo) is untested
Severity: low | Confidence: 0.75 | Effort: S
Where:
plugins/ca/hooks/taskwrite.py:80-83
.github/scripts/test_taskwriter.py:268-357
Evidence: taskwrite.py, the sole sanctioned mutator of .codearbiter/open-tasks.md, calls text = tb.read_board(board_path); if text is None: print(f"no board at {board_path} — is this an initialized repo?", file=sys.stderr); return 1 (lines 80-83). _taskboardlib.py's own module docstring flags read_board(path) -> str | None as an intentional library-level omission from unit testing, but that only excuses the reader itself; the CLI-level branch in taskwrite.py is a distinct, untested code path. Reading the entirety of TaskwriteCliTest (the only class exercising taskwrite.main directly) shows 5 tests, none of which points project_root() at a directory lacking .codearbiter/open-tasks.md; every test's _board() helper pre-creates the board file.
Impact: A data-mutation entry point invoked by /ca:task in every session; a regression that changes the missing-board message, the exit code, or accidentally falls through to a write attempt would not be caught. Low impact because the failure mode is a clear, loud stderr message rather than silent data loss, and the guard is a simple one-line None-check.
Recommendation: Add a TaskwriteCliTest case that points project_root() at a fresh tempdir with no .codearbiter/ directory and asserts taskwrite.main(['add', 'x']) returns 1 with the "no board at" message on stderr, and that no file was created.
Acceptance criteria:
- A test invokes taskwrite.main against a directory with no .codearbiter/open-tasks.md and asserts exit code 1 and the expected stderr message
- The test asserts no board file was created as a side effect
taskwrite.py: missing-board error path (uninitialized repo) is untested
Severity: low | Confidence: 0.75 | Effort: S
Where:
plugins/ca/hooks/taskwrite.py:80-83
.github/scripts/test_taskwriter.py:268-357
Evidence: taskwrite.py, the sole sanctioned mutator of .codearbiter/open-tasks.md, calls
text = tb.read_board(board_path); if text is None: print(f"no board at {board_path} — is this an initialized repo?", file=sys.stderr); return 1(lines 80-83). _taskboardlib.py's own module docstring flagsread_board(path) -> str | Noneas an intentional library-level omission from unit testing, but that only excuses the reader itself; the CLI-level branch in taskwrite.py is a distinct, untested code path. Reading the entirety of TaskwriteCliTest (the only class exercising taskwrite.main directly) shows 5 tests, none of which points project_root() at a directory lacking .codearbiter/open-tasks.md; every test's _board() helper pre-creates the board file.Impact: A data-mutation entry point invoked by /ca:task in every session; a regression that changes the missing-board message, the exit code, or accidentally falls through to a write attempt would not be caught. Low impact because the failure mode is a clear, loud stderr message rather than silent data loss, and the guard is a simple one-line None-check.
Recommendation: Add a TaskwriteCliTest case that points project_root() at a fresh tempdir with no .codearbiter/ directory and asserts taskwrite.main(['add', 'x']) returns 1 with the "no board at" message on stderr, and that no file was created.
Acceptance criteria: