← Về thư mục
📄 / / root / .hermes / skills / software-development / hermes-kanban / SKILL.md

name: hermes-kanban title: Hermes Kanban — Setup & Task Architecture description: Configure and organize Hermes Kanban boards with proper task hierarchy for enterprise/IT-BA workflows. Covers board naming conventions, task ID dot-notation, dependency linking pitfalls, and profile-based assignment. trigger: | - User wants to set up / restructure a kanban board - User asks about task hierarchy or parent-child relationships - User needs to decompose a project into sub-tasks on the board - User complains about approval gate bypass or chain reaction domains: - hermes-agent - task-management - kanban


Hermes Kanban — Architecture & Setup Guide

📋 Department Governance — Single Source of Truth (SSOT)

🚫 DO NOT hardcode department mapping anywhere. The absolute source of truth is config/departments.json under /opt/ai-os/products/ceo/.

Architecture (Consumer Pattern)

config/departments.json  ←── SSOT (The only place to edit)
         │
         ├── hermes kanban create ── CLI source of truth for task creation.
         └── AGENTS.md            ── DERIVED DOCS. Mirror of the JSON content.

🚩 PITFALL: Redundancy & Duplication

🚩 PITFALL: Invisible Telegram Commands

🚩 PITFALL: Systemd Auto-Advance hijacking Manual Gate

Symptom: You set orchestrator to manual and write DỪNG LẠI (STOP) instructions in the task description. However, the system still auto-promotes/auto-executes downstream tasks.

Cause: The background kanban-server.service systemd service is active and runs its own autonomous dispatching/promotion cycles, ignoring the manual task body gates.

Fix: Stop and disable the service to prevent any automated board-state transitions:

systemctl stop kanban-server.service
systemctl disable kanban-server.service

Once disabled, all task state updates (todo -> ready -> running -> done) must be handled manually via SQLite command line or direct Python scripts.

🚩 PITFALL: "Invisible" task completion by AI workers

Rule 5 — Post-Action Kanban Audit (Auto-Refresh)

Rule 6 — Proactive Self-Audit & Self-Healing

🚩 PITFALL: After unblocking a blocked child, verify it actually resumed

🚩 PITFALL: Proactive progress updates after each meaningful milestone

🚩 PITFALL: The "Done" Trap — protocol violation

🚩 PITFALL: Silent Execution vs Proactive Updates

🚩 PITFALL: Grouping/tagging pipelines need a cleanup pass

🚩 PITFALL: Incomplete Table of Contents (ToC) Rendering

Reference pointers

🚩 PITFALL: Local done ≠ Remote done — verify external state before claiming complete

Sub-agent reports are not sufficient evidence. A sub-agent may report "file deleted" but only have removed it from the working tree without committing and pushing. Always verify against the actual remote service.

When the task involves external services (GitHub, API, web): 1. Commit and push the change locally. 2. Verify using the actual remote URL or API endpoint (curl, gh api). 3. Only then close the Kanban task.

Example — verifying SOUL.md deletion:

# ❌ INSUFFICIENT: sub-agent says "done"
"đã thấy soul được remove khỏi profile"

# ✅ CORRECT: verify remote before marking done
curl -s -o /dev/null -w "%{http_code}" "https://raw.githubusercontent.com/.../SOUL.md"
# Must return 404; 200 means the remote is out of sync
if [ "$(curl -s -o /dev/null -w '%{http_code}' 'https://raw.githubusercontent.com/.../SOUL.md')" = "404" ]; then
  hermes kanban complete t_xxxxx
else
  hermes kanban block t_xxxxx "Remote NOT in sync — curl returned 200, file still exists"
fi

Why this matters (from session 2026-07-14): - User found profiles/it-ai/SOUL.md still on GitHub despite sub-agent claiming "done" - Root cause: sub-agent deleted file locally but never pushed to remote - Fix: commit + push + verify raw URL → then mark complete - User frustration: "sao cứ báo là done rồi" — because agent trusted sub-agent without verifying remote

🚩 PITFALL: Only notify CEO at decision gates

Khi pipeline có bước Proposal/Review dành cho CEO: - Background worker làm các bước tiền đề (phân tích, nghiên cứu) tự động — không thông báo từng bước - Chỉ block task ở bước proposal, đưa CEO review + approve - Sau CEO approve → tiếp tục build → test → complete

# Pattern:
# Step A (prep, worker chạy ngầm) → propose (block) → CEO duyệt (unblock) → build → test
# Không gọi CEO lúc Step A đang chạy

# CEO message: "chỉ cần đưa tôi ở bước proposal thôi, còn lại tự ngầm"

🚩 PITFALL: Board context matters before assign/block/complete

If a task lookup unexpectedly returns no such task or a state-transition command says the task is unknown, verify the active board first. A task can exist on one board while the CLI is pointed at another.

Recovery pattern: 1. Run hermes kanban boards list to identify the active board. 2. Switch explicitly with hermes kanban boards switch <slug> before any reassignment or state transition. 3. Re-run hermes kanban show <task_id> to confirm the task is visible on the intended board. 4. Then perform assign, block, unblock, or complete.

Why this matters: in this session, the task was visible only after switching from an unrelated board to nv-office; assign succeeded, but complete/block failed until the board context was corrected. Also in this session, when claiming a task under the active board research-hub, if parent dependencies are still running (like t_53eca8c7), claim will fail with parents_not_done. If you need to force start/claim the task (e.g. you are performing manual fact-checking / verification while the parent review task is running), you must explicitly unlink them with hermes kanban unlink <parent_id> <child_id>, manual-promote with hermes kanban promote <task_id> --force, and then perform the claim action.

Related verification: after changing assignee for a review gate, immediately show the task again so the board state and assignee are confirmed together.

🚩 PITFALL: Claim rejection due to parent dependencies or profile mismatch

Symptom: You promote a task to ready using --force, but trying to claim it immediately fails with cannot claim <task_id>: status=todo lock=(none) or claim_rejected {'reason': 'parents_not_done'}.

Root Causes: 1. Runtime Dependency Check: The claim command enforces parent dependency checks at runtime. Even if a task is manually promoted to ready, if its parent tasks are not in done or archived status, the claim will be rejected and the task may revert to todo. 2. Profile/Assignee Mismatch: The terminal's active profile (e.g., default) does not match the task's assignee (e.g., reviewer). The environment variable HERMES_SESSION_PROFILE overrides the active profile selected via hermes profile use and can cause silent mismatches. 3. Todo/Lock State: If a task is in todo status on the board and has no active runner lock, direct execution claims will fail. It must be in ready (promoted) and you must assign it to your profile first.

Fix: 1. Unlink Parents: If you must work on the child task out of order, unlink it from the running parent task using hermes kanban unlink <parent_id> <child_id>, promote it with hermes kanban promote <task_id> --force, and then claim. 2. Match Profile & Assign: Assign the task to your target profile. Confirm the assignee in hermes kanban show <task_id>. Verify your active profile via hermes config show. If they mismatch, switch profile and explicitly export the session profile: bash hermes profile use <assignee> export HERMES_SESSION_PROFILE=<assignee> 3. Claim: Run hermes kanban claim <task_id>. If it still fails with cannot claim: status=todo, double check that the task status is indeed ready and the assignee is correct. If the task is blocked by a running parent that you cannot unlink, you must wait for the parent to finish or force promote the task to ready before claiming.

Reference pointer

Reference pointer

When ALL tasks in a pipeline/umbrella are done (whether by spawned workers or direct agent execution), the agent MUST immediately send a final deliverable summary to the CEO in the current conversation. Do not wait for them to ask "tiến độ tới đâu rồi".

🚩 PITFALL: CEO review handoff must include a clickable review bundle

When reassigning a research or approval task to ceo, do not just change assignee and write "ready for review". The CEO needs a review packet on the task itself: 1. A clean clickable Markdown link to the exact deliverable file. 2. The specific review question or decision gate. 3. A short list of claims, sources, or assumptions to verify. 4. The current QA status and any caveats.

For this user's environment, file links MUST use the public Tailscale funnel format: https://vmi3427693.tail8c1aaf.ts.net/files/<absolute_path>

Example: [research_brief.md](https://vmi3427693.tail8c1aaf.ts.net/files/opt/ai-os/products/ceo/content/research/tourism_benchmarking/research_brief.md)

Never use plain http://100.71.157.103:9120 links in CEO-facing task comments. Plain URLs and private IP links force copy/paste and break mobile review flow.

🚩 PITFALL: Context management and breaking phases

To prevent context overflow and subagent degradation in multi-country research tasks, avoid combining all countries or too many steps into a single phase or single long task. Split large research pipelines into smaller, bite-sized tasks (e.g. separate Brief, separate extraction, separate Gap analysis, separate report) and link them appropriately. This keeps each run focused and within limits.

This applies even if the agent executed the work directly in the same conversation (not via spawned workers). The CEO expects a structured handoff, not silence followed by "đã xong hết rồi" as a reaction to being asked.

User's exact frustration (from session): "tiến độ tới đâu rồi làm xong hay chưa sao cũng ko thấy báo cáo gì" — this is a signal that the agent finished but failed to wrap up. Never let this happen.

When the trigger fires: - A hermes kanban create batch completes → summarize all created tasks - A hermes kanban complete is called on the last task in a pipeline → summarize the whole pipeline - A background process finishes with tasks now all done → poll and summarize - Negative example: agent finishes WR.11.03→11.05 (all done), but says nothing → CEO has to ask "tiến độ tới đâu rồi" ❌

The summary must include: - Which tasks completed (id + title + status) - Deliverable locations (absolute file paths — SOUL.md, config.yaml, etc.) - How to verify or use the result (e.g. CLI command to test, URL to open) - What's next (e.g. "Personality đã active — dùng /personality policy_researcher ở mọi thread")

## ✅ Hoàn thành WR.11

| Task | Kết quả |
|:-----|:--------|
| WR.11.03 | ✅ Proposal |
| WR.11.04 | ✅ Build — SOUL.md tại /root/... |
| WR.11.05 | ✅ Test — OK trên cả 2 thread |

## 📦 Dùng ngay
- `/personality policy_researcher` — mọi thread
- SOUL.md đã cập nhật cho R&D profile

Do NOT ask the CEO "đã xong chưa/có cần gì nữa không" — they expect you to report proactively and completely, then wait for their next instruction.

🚩 PITFALL: Task numbering mismatch during rename

When renaming task titles to fix numbering (e.g. Proposal should be WR.11.03, Build should be WR.11.04), the task ID never changes — only the title changes. This can cause confusion:

  1. The user sees the title on the board/dashboard
  2. They remember the old number and expect different logic
  3. The visual mismatch leads to "sai thứ tự" complaints even when the STATUS is correct

Pattern đúng:

# Xác định task nào là Proposal, task nào là Build trước
python3 -c "
import sqlite3
c = sqlite3.connect('/root/.hermes/kanban/boards/nv-office/kanban.db')
rows = c.execute('SELECT id, title, status FROM tasks WHERE title LIKE \"%WR.11%\"').fetchall()
for r in rows: print(f'{r[0]}: {r[2]} — {r[1]}')
"
# Chỉ swap title khi thực sự cần, và verify bằng list
hermes kanban list

🚩 PITFALL: Hermes Dashboard (9119) vs Custom Server — đọc cùng DB nhưng board khác nhau

Hermes Dashboard (port 9119) đọc mặc định board default, không phải board nv-office. Khi user thấy dữ liệu không khớp: - Không đổ lỗi cache — kiểm tra tenant selector trên giao diện Dashboard - Giao diện Dashboard có dropdown TENANT ở góc trên bên trái - User cần chọn đúng board nv-office để thấy dữ liệu chính xác

# Xác nhận nhanh DB nào đang dùng cho board nào:
# Dashboard mặc định: /root/.hermes/kanban.db (default board)
# NV-Office board:   /root/.hermes/kanban/boards/nv-office/kanban.db

Không bao giờ hỏi user "anh đang xem dashboard 9119 hay 9120" — họ không phân biệt được. Thay vào đó kiểm tra chính mình bằng SQLite query và hướng dẫn họ chọn đúng tenant.

🚩 PITFALL: Tạo task trên board riêng rồi quên switch/báo board hiện hành

Khi tạo một board mới cho workstream riêng (ví dụ brand-monitoring), user rất dễ nói "không thấy task trên Kanban" hoặc "bạn có thể unblock được không" nếu agent đứng ở board cũ (nv-office) hoặc không nói rõ task đang nằm ở board nào.

Pattern đúng: 1. Sau hermes kanban boards create <slug>switch <slug>, phải báo rõ board slug đang dùng. 2. Khi gửi task ID cho user, luôn nói rõ task thuộc board nào để họ xem đúng tenant/board. 3. Khi thao tác CLI (show, unblock, comment) báo unknown task hoặc no such task, kiểm tra ngay hermes kanban boards list để xem current board trước khi kết luận lỗi. 4. Luôn switch <slug> về đúng board rồi mới thao tác (unblock, comment, show).

Ví dụ thực chiến: - Tạo board brand-monitoring và tạo task t_7f5461eb trên board đó - Khi user yêu cầu unblock, nếu current board quay về nv-office, lệnh unblock t_7f5461eb sẽ fail với no such task - Cách xử lý chuẩn: hermes kanban boards list → phát hiện current board là nv-officehermes kanban boards switch brand-monitoringhermes kanban unblock t_7f5461eb

🚩 PITFALL: SOUL.md Identity Standardization & Pitfalls (2026-07-14)

Layered identity architecture (bottom to top): | Layer | Scope | File / Command | |:------|:------|:---------------| | SOUL.md | Whole instance | ~/.hermes/SOUL.md | | Profile Description | Per department | hermes profile describe <name> --text "..." | | AGENTS.md | Per project repo | ./AGENTS.md | | /personality | Per session (overlay) | /personality <name> in chat |

Verification:

grep -A 5 '<personality-name>' /root/.hermes/config.yaml
# Ensure no local profile identity files remain:
find /root/.hermes/profiles/ -name "*SOUL.md"

Reference file: skill_view(name='hermes-kanban', file_path='references/personality-soul-integration.md') — decision framework for partitioning content between SOUL.md and personality configs.

🚩 PITFALL: Personality prompt size limit via CLI

hermes config set personalities.<name> '<prompt>' has an implicit size limit from the CLI argument parser — very long prompts with multi-line content may be silently truncated or rejected.

Symptoms: The personality appears in config.yaml but is truncated (missing sections). The /personality command activates but the behavior doesn't match the full prompt.

Mitigation: Keep the personality prompt concise — focus on style, domain knowledge, and writing rules. Reserve detailed knowledge (terminology tables, long examples) for SOUL.md. The config.yaml personality is meant to be a lightweight behavior modifier, not a full knowledge dump.

If truncation happens: Edit ~/.hermes/config.yaml directly with a text editor (but note the patch tool may refuse for security — use hermes config set or the file editor with caution).

🚩 PITFALL: Kanban server crash — html variable name shadowing

If kanban_server.py crashes with: Error: cannot access local variable 'html' where it is not associated with a value

Check the top of the file for:

import html  # ← Python stdlib module

And then in the same file, a local variable named html:

html += `...`  # ← string concatenation using 'html' as a variable

The local variable html shadows the imported module html. If the local variable is assigned but the assignment branch doesn't execute (e.g. an exception before the assignment), Python raises UnboundLocalError on the next reference.

Fix: Rename either the import or the variable: - Use import html as htmllib (then call htmllib.escape()) - Or rename the local variable to html_buf or output_html

🚩 PITFALL: Unassigned orphans from batch creation

🚩 PITFALL: Insufficient Task Body & Missing Personality Definition

Symptom: User questions how a Kanban task "understands its mission" or asks "where personality is defined" for a given task/phase. Kanban task bodies are overly brief, relying on external delegation context that is not persistent.

Root Cause: 1. Over-reliance on delegate_task's goal/context parameters to convey full task instructions and agent Personality. This makes Kanban tasks non-self-contained and vulnerable to context loss. 2. Lack of explicit Personality mapping in the overall research plan or task templates.

Fix: 1. Self-contained Task Bodies: For every Kanban task, ensure its body field is comprehensive and self-contained. This includes: * CONTEXT: Absolute paths to critical reference files (research_plan.md, research_output_template.md, etc.). * PERSONALITY: Explicitly assign the Personality (e.g., Policy Researcher, Institutional Strategist) required for the agent executing this task. * MỤC TIÊU (Objectives): Clear, detailed goals and scope for the task. * OUTPUT: Required deliverable files, format, and storage locations. * MANUAL GATE: Clear instructions for pausing and awaiting human review. 2. Explicit Personality Map in Research Plan: Define a "Personality Map" section in the top-level research_plan.md (or similar project plan) that assigns a specific personality to each major pipeline phase. This provides a central reference. 3. Template Integration: Embed the required personality directly into phase-specific templates (e.g., research_output_template.md) for phases where a particular writing style or analytical approach is critical.

This ensures tasks are robust, transparent, and consistently executed with the desired voice and analytical rigor.