BACK-494 - Backlog-Guard: PreToolUse hook to enforce MCP/CLI access to backlog directories#649
Open
lenucksi wants to merge 49 commits into
Open
BACK-494 - Backlog-Guard: PreToolUse hook to enforce MCP/CLI access to backlog directories#649lenucksi wants to merge 49 commits into
lenucksi wants to merge 49 commits into
Conversation
- Add terminalStatuses?: string[] to BacklogConfig interface - Parse terminal_statuses key in config loader (same pattern as statuses) - Extend getTerminalStatus/isTerminalStatus with optional terminalStatuses param - Falls back to last-element convention when not provided (backward-compatible) - isTerminalStatus returns true for any entry in terminalStatuses array - getTerminalStatus returns terminalStatuses[0] as primary terminal status - Add 5 new test cases covering multi-terminal, fallback, empty-array, and non-last-element override scenarios Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
BACK-465 - Config-Schema: terminalStatuses-Key einführen
…atistics, milestones, handlers Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…uences and board filters Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…x serializeConfig Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Added 4 tests to src/web/lib/lanes.test.ts covering the sortTasksForStatus refactoring from BACK-467: custom terminal status gets done-sort even when not last in statuses array, empty terminalStatuses falls back to last-element convention, and active statuses are unaffected when terminalStatuses is set. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…tyling
- Add blockedStatuses?: string[] to BacklogConfig type
- Parse/serialize blocked_statuses in parseConfig/serializeConfig (same pattern as terminalStatuses)
- Extend getStatusStyle(), getStatusColor(), getStatusIcon(), formatStatusWithIcon() to accept optional blockedStatuses param
- Config-aware check runs first; falls back to exact-match statusMap ("Blocked") and substring heuristic (includes("blocked"))
- Thread blockedStatuses prop through App.tsx -> BoardPage -> Board -> TaskColumn
- Update getStatusBadgeClass() in TaskColumn: config array checked first, then fallback includes("blocked")/includes("stuck")
- Add 3 new tests (RED confirmed before implementation)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…HEAD Replace git rev-list --all --count with git rev-list --count HEAD in getCommitCountInTest. The --all flag includes refs/notes/ai commits created asynchronously by the global git-ai trace2 tool, inflating counts non-deterministically. HEAD-scoped counting matches the approach in cli.test.ts and correctly measures commits on the current branch. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…HEAD Replace git rev-list --all --count with git rev-list --count HEAD in getCommitCountInTest. The --all flag includes refs/notes/ai commits created asynchronously by the global git-ai trace2 tool, inflating counts non-deterministically. HEAD-scoped counting matches the approach in cli.test.ts and correctly measures commits on the current branch. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Commit all untracked backlog task files (back-465 through back-482) and update modified task files (back-200 through back-438) to establish a safe baseline before upstream PR rebase operations. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Upstream version-bump CI commit used 2-space indent; reformat to tabs to match the project Biome config and unblock `bun run check .`. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Renamed back-466/back-467 task files from German to English names. Translated implementation notes in back-469 to English. BACK-480 marked Done with full notes and final summary. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Exclude package.json from Biome's formatter via overrides to prevent tabs-vs-spaces conflicts on every pull from upstream, which uses spaces. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
style.css is rebuilt by build:css before every build/cli invocation; committing it caused noisy 200KB single-line diffs on any CSS change. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
New tasks: - BACK-486: Colored Labels (WebUI/TUI/CLI/MCP/REST) - BACK-487: Labels for Documents and Decisions - BACK-488: Label Management — central CRUD + autocomplete - BACK-489: Archive Documents and Decisions + superseded ADRs - BACK-490: REST API OpenAPI self-documentation - BACK-491: Cross-Modality CI — enforce feature parity - BACK-492: Tech Debt Research — codebase audit Updated: - BACK-474: recycled from German stub → Sequence/Dependency Visualizer Research (audits BACK-217/218 cluster, library eval, no code) - BACK-484: fleshed out assignee autocomplete stub with description + AC (scraping-based, no central config) All tickets include upstream-master constraint block and explicit 5-modality AC. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- BACK-466/467: translate implementation notes and titles to English (BACK-480 follow-up) - BACK-479/481/482: mark Done, check off all ACs, add Final Summary sections - BACK-478: remove task (superseded by BACK-479–482) - BACK-483: add new task (subtasks / Epic-level tracking question) - .gitignore: ignore archive/ directory Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Previously the milestones page sorted milestone cards by ID descending (newest first), so a project with phases m-3 through m-6 would display Phase 9 (m-6) at the top, followed by Phase 7 (m-4) and Phase 8 (m-5). This reverses the sort to ascending so milestones appear in their natural creation order (m-1 → m-2 → m-3 … ), matching the sequence users intend when they create milestones in phase/sprint order.
The task list view (web UI + CLI) previously only supported sorting by id and priority. Tasks have an ordinal field used for manual wave-based ordering, which the board view already respects — but the list view ignored it entirely, showing tasks in ID order with no way to recover the deliberate sequence. Changes: - TaskList.tsx: add "ordinal" to TaskSortColumn union type; add ordinal sort case in sortedDisplayTasks useMemo (tasks with ordinals come first, then ascending by ordinal value, matching board view behavior); add sortable "Ordinal" column header and data cell in the table - cli.ts: add "ordinal" to validSortFields in all four task list/draft list call sites; update --sort option help text accordingly Closes MrLesk#643
…o backlog dirs Adds hooks/backlog-guard/ — a hard-blocking PreToolUse hook that intercepts Read/Edit/Write/Bash operations on files inside configured backlog directories and redirects the agent to the correct MCP tool or CLI command. Config via .backlog-guard YAML at git root (auto-discovered via git rev-parse); falls back to auto-detecting backlog/config.yml in the directory tree. Block messages include the exact MCP call and CLI command, with task ID extracted from the filename (back-NNN-title.md) for task files. Also adds .codex/skills/backlog-guard-setup/SKILL.md — a setup skill that auto-detects the backlog directory, creates .backlog-guard, writes the hook entry into the appropriate settings file, and optionally adds mcp__backlog__* allowlist entries. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…aths - Add Grep tool handling: block when path resolves under protected dir; suggest task_search for tasks, document_search for docs - Write with no task ID in filename now suggests task_create instead of task_edit; Write to new doc path suggests document_create instead of document_update - classify_path now covers completed/, drafts/, decisions/ directories - _generic_suggestions handles decision type (search suggestion) - Matcher updated to Read|Edit|Write|Bash|Grep in README and setup skill - 4 new tests (12 total, all passing) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
hooks/backlog-guard introduces .py and .sh files; adding these languages enables LSP support for the new hook files in the Serena project. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
hooks/backlog-guard introduces .py and .sh files; adding these languages enables LSP support for the new hook files in the Serena project. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Add isPortAvailable() and findNextAvailablePort() to server/index.ts, pre-check port in CLI browser command, prompt user to start on next free port if taken. Simplify EADDRINUSE catch (UX now in CLI).
# Conflicts: # backlog/tasks/back-473 - handle-port-congestion-for-backlog-browser.md
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…Code and OpenCode Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
05c0f69 to
17a4aab
Compare
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…cate cleanup - Created 6 new milestones (m-7 through m-13) covering Forge Integration, Web UI Polish, Task Schema & Metadata, Subtasks & Dependencies, Agent & IDE Integrations, CLI & TUI Enhancements, and Infrastructure & DevEx - Assigned all ~80 open tasks to milestones - Closed BACK-222 and BACK-483 as duplicates of the BACK-493 cluster - Marked BACK-420 as sub-concern of BACK-260; added cross-references - Added dependency and relationship notes across BACK-239/477, BACK-349/200/310, and the BACK-474/217 sequence cluster - Set priorities on all previously unprioritized open tasks (1× high, 14× medium, 16× low) - Added dependency chains: 268→267, 487→486, 488→486, 504→500+503, 506→260 - Added BACK-506 (batch operations in All Tasks view) to Web UI Polish milestone Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Research pass identifying DRY/KISS violations, pattern inconsistencies, and static analysis tooling options. Output: doc-004 in backlog/docs/. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Internal audit document (doc-004) — not for upstream PR.
4 additional DRY/KISS violations: core.fs vs core.filesystem accessor inconsistency, duplicate ensureInitialized pattern, error surface fragmentation across modalities, repeated listMilestones Promise.all. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Create doc-005 with full CLI/TUI/WebUI/MCP feature matrix across 9 domains. Create BACK-492 subtasks .1–.7 from audit stubs A–G with full ACs and implementation plans. Keep BACK-492 In Progress pending subtask completion. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…l summary Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Milestone cards sort by ID ascending (m-1 before m-2). Tests used [0] to pick the first Edit/Remove button but expected m-2 (Release 2) behavior. Changed [0] to [1] to match actual card ordering.
…Code and OpenCode Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…Claude Code + OpenCode, dual MCP naming, Claude Code plugin structure, marketplace, skills
17a4aab to
0d84d25
Compare
…publish workflow - packages/backlog-guard/package.json - scoped npm package for OpenCode plugin - .github/workflows/publish-backlog-guard.yml - publish on push/tag/manual - dev.sh copies compiled opencode-plugin.js into the package
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
hooks/backlog-guard/— a Claude CodePreToolUsehook that hard-blocks directRead/Edit/Write/Bashaccess to configured backlog directories and redirects agents to the correct MCP tool or CLI command with pre-filled parameters (task ID extracted from filename, document name, etc.).backlog-guardYAML file at git root, auto-discovered viagit rev-parse --show-toplevel; falls back to detectingbacklog/config.ymlin the directory tree (no configuration needed for standard single-backlog projects).codex/skills/backlog-guard-setup/SKILL.md— a one-command setup skill that auto-detects the backlog directory, creates.backlog-guard, writes the hook entry into the appropriate settings file, and optionally addsmcp__backlog__*tool permissions to the allowlist__pycache__/and*.pycto.gitignoreTest plan
python -m pytest hooks/backlog-guard/test_check.py -v— 8 tests passReadonbacklog/tasks/back-1-...md→ denied,BACK-1in reason, MCP + CLI suggestion in contextReadonsrc/cli.ts→ allowed (not in backlog dir)Bash(cat backlog/tasks/back-1-...md)→ deniedgrep pattern file.txt | grep back-123→ allowed (pipeline stdin, not file arg).backlog-guard,backlog/config.ymlpresent → auto-detect still blocks/backlog-guard-setupskill →.backlog-guardcreated, settings hook entry writtenBlock message example
When an agent tries
Read(backlog/tasks/back-494 - Backlog-Guard-....md):🤖 Generated with Claude Code