1. KanbanBoard now consumes pendingTaskId from ViewContext
- Clicking status history entry navigates to board AND opens task detail
- Fetches task from API if not in current filtered list
2. Status history now captures taskId/taskTitle from activeAgents
- When status changes via activeAgents (not activeTask), derive task info
- Falls back to first activeAgent's taskId/taskTitle
- Fixes missing titles in ~90% of status history entries
- Add onTaskClick prop to StatusHistoryPanel
- Make rows clickable when taskId is present
- Task title shows as link style (primary color + underline on hover)
- Keyboard accessible (Enter/Space to click)
- Falls back to em-dash when no task title
- Add comprehensive ANALYTICS.md documenting all endpoints
- Document data models, metrics, and usage examples
- Add TESTING_ANALYTICS.md with test scenarios
- Update swagger.ts with analytics schemas and endpoints
- Include performance benchmarks and troubleshooting guide
Add pre-transition gates that must pass before status change is allowed:
- require-agent: Task must have agent assigned
- require-plan: Description must contain Plan section
- require-verification-complete: All verification steps checked
- require-time-tracked: Time tracking must have entries
- require-closing-comment: Task must have at least one comment
- require-subtasks-complete: All subtasks completed
- require-blocker-reason: blockedReason must be set
Add post-transition actions that fire after status change:
- auto-start-timer: Start time tracking
- auto-stop-timer: Stop time tracking
- send-webhook: POST to URL
- send-notification: Send to channel
- prompt-lessons-learned: Flag for capture
- log-activity: Log to activity feed
API:
- GET/PUT/PATCH /api/settings/transition-hooks
- POST /api/settings/transition-hooks/validate
- CRUD for individual rules at /api/settings/transition-hooks/rules
Config stored in .veritas-kanban/transition-hooks.json
Also adds 'cancelled' status and 'critical' priority to shared types.
Ref: task_20260201_04iPHh
Added docs/SOP-shared-resources.md covering:
- Single repo vs multi-repo directory structures
- Mounting strategies (copy, symlinks, git submodules, npm packages)
- What to share vs what to keep project-specific
- Referencing shared resources in tasks and prompts
- Versioning and update protocols
- Migration checklist
Updated GETTING-STARTED.md to reference the new prompt-registry templates.
Credit: BoardKit Orchestrator (Monika Voutov) for the shared resources pattern.
Closes#77
New CLI command that validates environment and helps new users get started:
- Checks Node version (requires >=18)
- Verifies server is running and accessible
- Tests API authentication
- Optionally creates a welcome task with next steps
- Supports --json output for automation
- Supports --skip-task to skip sample task creation
Updated docs/GETTING-STARTED.md to reference the new command.
Credit: BoardKit Orchestrator (Monika Voutov) for the wizard pattern inspiration.
Closes#71
Extended path traversal protection to two services missed in initial audit:
- trace-service.ts: validate attemptId, taskId, traceId before path.join
- template-service.ts: validate templateId in templatePath()
Both now use validatePathSegment() + ensureWithinBase() from utils/sanitize.ts.
Ref: RF-002a Batch 3a Findings (High+Medium severity)
Bug 1: /api/metrics/all was passing the period filter to task counts,
showing only tasks touched within the time window (e.g., 33 todo in 24h)
instead of current board state (124 todo total).
Fix: computeAllMetrics now passes null to computeTaskMetrics so task
status counts always reflect current state. Period filter still applies
to telemetry metrics (runs, tokens, duration).
Bug 2: /api/backlog/count was double-wrapping response (route wrapped
with success/data, then middleware wrapped again).
Fix: Route now returns { count } and lets responseEnvelopeMiddleware
handle wrapping.
Bug: taskToFilename() generates filename from current title, but the
actual file on disk may have a different slug if the title changed after
creation. This caused INTERNAL_ERROR on archive/delete/restore.
Fix: Added findTaskFile() helper that searches by task ID prefix instead
of computing the expected filename. Applied to archiveTask, deleteTask,
and restoreTask.
Also: archiveSprint now throws ValidationError instead of generic Error
for better API error responses.
tasks/backlog/*.md and tasks/examples/*.md were not covered by
.gitignore — only active/ and archive/ were. Added both patterns
and removed 56 tracked task files from the index.
Files remain on disk (only removed from git tracking).
SEC-001: Path traversal prevention
- Add validatePathSegment() and ensureWithinBase() to server/src/utils/sanitize.ts
- Apply to chat-service (sessionId/taskId in file paths)
- Apply to conflict-service (filePath in path.join)
- Apply to clawdbot-agent-service (taskId/attemptId in log/request paths)
SEC-007: Admin authorization on mutating endpoints
- settings.ts: PATCH /features requires authorize('admin')
- config.ts: POST/PATCH/DELETE repos, PUT agents, PUT default-agent
- activity.ts: DELETE / requires authorize('admin')
- notifications.ts: POST/mark-sent/check require authorize('admin','agent'), DELETE requires admin
- status-history.ts: DELETE / requires authorize('admin')
- Updated test harnesses with admin auth injection
Agent Status Indicator: WebSocket fix
- BoardSidebar now uses useRealtimeAgentStatus (WebSocket) instead of useGlobalAgentStatus (polling)
- Fixed field name mismatch: server broadcasts 'activeAgents' but hook expected 'subAgents'
- Hook now correctly reads activeAgents from both WebSocket messages and REST fallback
- Added connection status indicator and stale detection to sidebar
- Fixed agent-status.ts spread order for persisted status restore
Pre-existing fixes included (from earlier RF-002 sub-agent diffs):
- auth.ts: X-Forwarded-For only trusted when trust proxy configured
- rate-limit.ts: isLocalhost returns false in production
- telemetry-service: CSV formula injection prefix sanitization
- Frontend: window.open noopener/noreferrer on all instances
The agent status indicator on the VK board was not updating during
sub-agent workloads because OpenClaw sub-agents (spawned via
sessions_spawn) run outside VK's clawdbot-agent-service — nothing
was POSTing to /api/agent/status.
Server fix:
- Reset subAgentCount to 0 when status transitions to idle
(previously only cleared activeTask, errorMessage, and activeAgents)
Workflow fix (in clawd workspace):
- Created vk-status.sh script to wrap the agent status API
- Added mandatory SOP to AGENTS.md: orchestrator calls vk-status.sh
before/after every spawn, and every sub-agent task prompt includes
a curl POST to /api/agent/status as its first action
- Works regardless of which model runs the sub-agent (Codex, Sonnet,
GPT, etc.) — both the orchestrator and the agent itself report in
- Remove container max-width from main layout — all views now full-width
- Convert Archive from sidebar to full page with search, filters, bulk restore
- Add Archive nav button in header (replaces sidebar icon)
- Archive page matches Backlog/Activity design: expand-in-place, checkboxes, badges
- Sprint filter on archive page
- Consistent UX across Board, Activity, Backlog, and Archive views
- Add Status History tab with day-grouped status transitions
- Add Daily Summary tab with active/idle/utilization metrics
- Remove Activity Sidebar component and its header icon
- Single 'Activity' nav button now opens the unified feed page
- Agent status indicator links to activity feed instead of sidebar
- Closes#66
Previously clicking a task in the backlog called navigateToTask which
switched back to the board view. Now tasks expand/collapse inline with
full description, dates, agent, and recent comments.
Fixes YAMLException when creating backlog tasks - undefined frontmatter
fields were being passed to gray-matter stringify which can't serialize
them. Now filters out undefined values before serialization.
- Add BacklogRepository for file-based storage in tasks/backlog/
- Add BacklogService with promote/demote logic
- Add backlog API routes (list, create, update, delete, promote, demote)
- Add BacklogPage component with search, filtering, and bulk actions
- Add backlog navigation with task count badge in header
- Add 'Move to Backlog' action to bulk actions bar
- Add CLI commands: backlog list/add/promote/demote/delete/count
- Add activity types for task_promoted and task_demoted events
- Backlog tasks are stored separately and not loaded by main task service
- Tasks can be promoted from backlog to active board (status -> todo)
- Tasks can be demoted from active board to backlog
Previously the 'Move to...' dropdown fired immediately on selection with
no confirm step. Now it's a two-step flow: pick target status from dropdown,
then click 'Move' button to confirm — consistent with Archive and Delete.
Fixes task_20260201_NqmOuf