dw-kit 1.4.0 → 1.7.0-rc.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (65) hide show
  1. package/.claude/agents/executor.md +80 -80
  2. package/.claude/hooks/pre-commit-gate.sh +59 -0
  3. package/.claude/hooks/stop-check.sh +111 -31
  4. package/.claude/rules/commit-standards.md +48 -37
  5. package/.claude/rules/dw.md +47 -11
  6. package/.claude/skills/dw-commit/SKILL.md +7 -4
  7. package/.claude/skills/dw-decision/SKILL.md +5 -4
  8. package/.claude/skills/dw-execute/SKILL.md +18 -5
  9. package/.claude/skills/dw-handoff/SKILL.md +8 -3
  10. package/.claude/skills/dw-plan/SKILL.md +15 -2
  11. package/.claude/skills/dw-research/SKILL.md +7 -5
  12. package/.claude/skills/dw-retroactive/SKILL.md +75 -63
  13. package/.claude/skills/dw-task-init/SKILL.md +40 -35
  14. package/.dw/adapters/generic/AGENT.md +171 -169
  15. package/.dw/core/WORKFLOW.md +450 -450
  16. package/.dw/core/schemas/agent-claim.schema.json +127 -0
  17. package/.dw/core/schemas/agent-report.schema.json +72 -0
  18. package/.dw/core/schemas/goal-frontmatter.schema.json +84 -0
  19. package/.dw/core/schemas/task-frontmatter.schema.json +97 -0
  20. package/.dw/core/templates/v3/goal.md +146 -0
  21. package/.dw/core/templates/v3/task.md +188 -0
  22. package/CLAUDE.md +2 -2
  23. package/MIGRATION-v1.5.md +330 -0
  24. package/README.md +17 -0
  25. package/package.json +3 -2
  26. package/src/cli.mjs +312 -0
  27. package/src/commands/agent-claim.mjs +235 -0
  28. package/src/commands/agent-inspect.mjs +123 -0
  29. package/src/commands/doctor.mjs +64 -0
  30. package/src/commands/goal-bump.mjs +50 -0
  31. package/src/commands/goal-delete.mjs +120 -0
  32. package/src/commands/goal-link.mjs +126 -0
  33. package/src/commands/goal-lint.mjs +152 -0
  34. package/src/commands/goal-new.mjs +86 -0
  35. package/src/commands/goal-portfolio.mjs +84 -0
  36. package/src/commands/goal-render.mjs +49 -0
  37. package/src/commands/goal-set.mjs +62 -0
  38. package/src/commands/goal-show.mjs +94 -0
  39. package/src/commands/goal-stubs.mjs +21 -0
  40. package/src/commands/goal-suggest-krs.mjs +139 -0
  41. package/src/commands/goal-summary.mjs +67 -0
  42. package/src/commands/goal-view.mjs +196 -0
  43. package/src/commands/lint-task.mjs +112 -0
  44. package/src/commands/task-migrate.mjs +471 -0
  45. package/src/commands/task-new.mjs +90 -0
  46. package/src/commands/task-render.mjs +235 -0
  47. package/src/commands/task-rotate.mjs +168 -0
  48. package/src/commands/task-show.mjs +137 -0
  49. package/src/commands/task-summary.mjs +68 -0
  50. package/src/commands/task-view.mjs +386 -0
  51. package/src/commands/task-watch.mjs +868 -0
  52. package/src/lib/active-index.mjs +19 -1
  53. package/src/lib/agent-claim.mjs +173 -0
  54. package/src/lib/agent-conflict.mjs +137 -0
  55. package/src/lib/agent-events.mjs +43 -0
  56. package/src/lib/agent-report.mjs +96 -0
  57. package/src/lib/frontmatter.mjs +72 -0
  58. package/src/lib/goal-events.mjs +79 -0
  59. package/src/lib/goal-store.mjs +202 -0
  60. package/src/lib/goal-svg.mjs +293 -0
  61. package/src/lib/goal-watch.mjs +133 -0
  62. package/src/lib/lint-rules.mjs +149 -0
  63. package/src/lib/sse-broker.mjs +91 -0
  64. package/src/lib/timeline-parser.mjs +80 -0
  65. package/src/lib/watch-auth.mjs +64 -0
@@ -1,80 +1,80 @@
1
- ---
2
- name: executor
3
- description: "Agent thực hiện implementation theo plan đã approve. Có thể chạy trong isolated worktree. Tuân thủ TDD, commit sau mỗi subtask."
4
- tools:
5
- - Read
6
- - Write
7
- - Edit
8
- - Bash
9
- - Grep
10
- - Glob
11
- - Agent
12
- disallowedTools:
13
- - NotebookEdit
14
- model: inherit
15
- ---
16
-
17
- # Executor Agent
18
-
19
- Bạn là Senior Developer thực hiện implementation. Nhiệm vụ: execute plan đã được approve, tuân thủ TDD, commit sau mỗi subtask.
20
-
21
- ## Nguyên Tắc
22
-
23
- 1. **Đọc plan trước mỗi subtask** — không làm từ memory
24
- 2. **Chỉ làm đúng scope** — không "while I'm here" fixes
25
- 3. **TDD**: Test trước → implement → refactor → commit
26
- 4. **Gặp ambiguity** → DỪNG và hỏi human, không tự suy diễn
27
- 5. **Scope thay đổi** → cập nhật plan, hỏi human trước khi tiếp tục
28
- 6. **Mỗi subtask done** → update progress file + commit
29
-
30
- ## TDD Workflow (mỗi subtask)
31
-
32
- ```
33
- 1. Đọc acceptance criteria của subtask
34
- 2. Viết test mô tả expected behavior → RED (failing)
35
- 3. Implement tối thiểu để test pass → GREEN
36
- 4. Refactor nếu cần (không thay đổi tests) → REFACTOR
37
- 5. Verify: không còn debug code
38
- 6. Update progress file: subtask status → Done
39
- 7. Commit: git commit -m "type(scope): description"
40
- ```
41
-
42
- ## Khi Gặp Blocker
43
-
44
- ```
45
- 1. Ghi blocker vào progress file với mô tả đầy đủ
46
- 2. Xác định: có thể self-resolve không?
47
- - Có: document approach, proceed
48
- - Không: DỪNG, escalate rõ ràng
49
- 3. KHÔNG silent-skip subtask
50
- 4. KHÔNG self-approve scope changes
51
- ```
52
-
53
- ## Worktree Mode (nếu được chỉ định)
54
-
55
- Khi task có risk cao (large refactor, breaking changes):
56
- - Xác nhận với human: "Task này có risk cao. Nên chạy trong isolated worktree. Confirm?"
57
- - Sau khi confirm: sử dụng isolation: "worktree" khi spawn sub-agents
58
- - Changes trong worktree không ảnh hưởng main branch cho đến khi human approve merge
59
-
60
- ## Pre-Commit Checklist (mỗi subtask)
61
-
62
- ```
63
- [ ] Logic đúng? Tests pass?
64
- [ ] Không còn console.log/debugger/var_dump
65
- [ ] Không có hardcoded credentials/tokens
66
- [ ] Commit message theo format: type(scope): description ≤72 chars
67
- [ ] Progress file updated
68
- ```
69
-
70
- ## Commit Format
71
-
72
- ```
73
- <type>(<scope>): < tả ≤72 ký tự>
74
-
75
- [Chi tiết nếu cần tại sao, không phải ]
76
-
77
- Co-Authored-By: Claude <noreply@anthropic.com>
78
- ```
79
-
80
- Types: `feat` `fix` `refactor` `test` `docs` `chore` `style` `perf`
1
+ ---
2
+ name: executor
3
+ description: "Agent thực hiện implementation theo plan đã approve. Có thể chạy trong isolated worktree. Tuân thủ TDD, commit sau mỗi subtask."
4
+ tools:
5
+ - Read
6
+ - Write
7
+ - Edit
8
+ - Bash
9
+ - Grep
10
+ - Glob
11
+ - Agent
12
+ disallowedTools:
13
+ - NotebookEdit
14
+ model: inherit
15
+ ---
16
+
17
+ # Executor Agent
18
+
19
+ Bạn là Senior Developer thực hiện implementation. Nhiệm vụ: execute plan đã được approve, tuân thủ TDD, commit sau mỗi subtask.
20
+
21
+ ## Nguyên Tắc
22
+
23
+ 1. **Đọc plan trước mỗi subtask** — không làm từ memory
24
+ 2. **Chỉ làm đúng scope** — không "while I'm here" fixes
25
+ 3. **TDD**: Test trước → implement → refactor → commit
26
+ 4. **Gặp ambiguity** → DỪNG và hỏi human, không tự suy diễn
27
+ 5. **Scope thay đổi** → cập nhật plan, hỏi human trước khi tiếp tục
28
+ 6. **Mỗi subtask done** → update progress file + commit
29
+
30
+ ## TDD Workflow (mỗi subtask)
31
+
32
+ ```
33
+ 1. Đọc acceptance criteria của subtask
34
+ 2. Viết test mô tả expected behavior → RED (failing)
35
+ 3. Implement tối thiểu để test pass → GREEN
36
+ 4. Refactor nếu cần (không thay đổi tests) → REFACTOR
37
+ 5. Verify: không còn debug code
38
+ 6. Update progress file: subtask status → Done
39
+ 7. Commit: git commit -m "type(scope): description"
40
+ ```
41
+
42
+ ## Khi Gặp Blocker
43
+
44
+ ```
45
+ 1. Ghi blocker vào progress file với mô tả đầy đủ
46
+ 2. Xác định: có thể self-resolve không?
47
+ - Có: document approach, proceed
48
+ - Không: DỪNG, escalate rõ ràng
49
+ 3. KHÔNG silent-skip subtask
50
+ 4. KHÔNG self-approve scope changes
51
+ ```
52
+
53
+ ## Worktree Mode (nếu được chỉ định)
54
+
55
+ Khi task có risk cao (large refactor, breaking changes):
56
+ - Xác nhận với human: "Task này có risk cao. Nên chạy trong isolated worktree. Confirm?"
57
+ - Sau khi confirm: sử dụng isolation: "worktree" khi spawn sub-agents
58
+ - Changes trong worktree không ảnh hưởng main branch cho đến khi human approve merge
59
+
60
+ ## Pre-Commit Checklist (mỗi subtask)
61
+
62
+ ```
63
+ [ ] Logic đúng? Tests pass?
64
+ [ ] Không còn console.log/debugger/var_dump
65
+ [ ] Không có hardcoded credentials/tokens
66
+ [ ] Commit message theo format: type(scope): description ≤72 chars
67
+ [ ] Progress file updated
68
+ ```
69
+
70
+ ## Commit Format
71
+
72
+ ```
73
+ <type>(<scope>): <imperative English ≤72 chars>
74
+
75
+ [Optional body explain WHY, not WHAT, wrap at 72]
76
+ ```
77
+
78
+ Types: `feat` `fix` `refactor` `test` `docs` `chore` `style` `perf`
79
+
80
+ English imperative mood. **Do not append `Co-Authored-By: Claude` or any AI signature.** Full rules: `.claude/rules/commit-standards.md`.
@@ -67,6 +67,65 @@ if [ -n "$STAGED_FILES" ]; then
67
67
  fi
68
68
  fi
69
69
 
70
+ # v1.5 (ADR-0008): v3 task.md SVG regen on staged commit
71
+ # Diff-aware — only render tasks whose task.md changed.
72
+ # Fail-graceful: sub-package absent → Mermaid fallback (in-md, no SVG needed).
73
+ # Auto-stage SVG if user opts-in to commit (gitignored by default per .gitignore).
74
+ DW_BIN="$CLAUDE_PROJECT_DIR/bin/dw.mjs"
75
+ if [ -f "$DW_BIN" ] && command -v node >/dev/null 2>&1 && [ -n "$STAGED_FILES" ]; then
76
+ TIMELINE_TASKS=$(echo "$STAGED_FILES" | grep -E '^\.dw/tasks/[^/]+/task\.md$' | sed -E 's|^\.dw/tasks/([^/]+)/task\.md$|\1|' | sort -u)
77
+ if [ -n "$TIMELINE_TASKS" ]; then
78
+ echo "📐 dw-kit: regenerating timeline.svg for staged task.md" >&2
79
+ while IFS= read -r task; do
80
+ [ -z "$task" ] && continue
81
+ node "$DW_BIN" task render "$task" >/dev/null 2>&1 || true
82
+ # Auto-stage SVG if not gitignored (opt-in projects)
83
+ SVG_FILE="$CLAUDE_PROJECT_DIR/.dw/tasks/$task/timeline.svg"
84
+ if [ -f "$SVG_FILE" ]; then
85
+ if ! git -C "$CLAUDE_PROJECT_DIR" check-ignore -q "$SVG_FILE" 2>/dev/null; then
86
+ git -C "$CLAUDE_PROJECT_DIR" add "$SVG_FILE" 2>/dev/null || true
87
+ echo " ✓ staged $task/timeline.svg" >&2
88
+ fi
89
+ fi
90
+ done <<EOF
91
+ $TIMELINE_TASKS
92
+ EOF
93
+ fi
94
+ fi
95
+
96
+ # v1.6 (ADR-0009 R2-2): Agent OS post-hoc check.
97
+ # When ≥1 active claim exists, verify staged files fall within an active claim's write_scope.
98
+ # Cooperative protocol — warn only (cannot prevent non-compliant agents).
99
+ if [ -f "$DW_BIN" ] && command -v node >/dev/null 2>&1 && [ -n "$STAGED_FILES" ]; then
100
+ CLAIMS_DIR="$CLAUDE_PROJECT_DIR/.dw/cache/agents/claims"
101
+ if [ -d "$CLAIMS_DIR" ] && ls "$CLAIMS_DIR"/*.json >/dev/null 2>&1; then
102
+ OUT_OF_SCOPE=$(STAGED="$STAGED_FILES" node -e "
103
+ const fs = require('fs');
104
+ const path = require('path');
105
+ (async () => {
106
+ const { listClaims } = await import('$CLAUDE_PROJECT_DIR/src/lib/agent-claim.mjs');
107
+ const { pathMatchesScope } = await import('$CLAUDE_PROJECT_DIR/src/lib/agent-conflict.mjs');
108
+ const claims = listClaims(process.env.CLAUDE_PROJECT_DIR || '$CLAUDE_PROJECT_DIR').filter(c => c._live_status === 'created' || c._live_status === 'active');
109
+ if (claims.length === 0) return;
110
+ const allScopes = claims.flatMap(c => c.write_scope);
111
+ const staged = (process.env.STAGED || '').split(/\r?\n/).filter(Boolean);
112
+ const outside = staged.filter(f => !pathMatchesScope(f, allScopes));
113
+ if (outside.length > 0) {
114
+ console.log('Files NOT in any active claim write_scope:');
115
+ for (const f of outside.slice(0, 10)) console.log(' ' + f);
116
+ if (outside.length > 10) console.log(' ... +' + (outside.length - 10) + ' more');
117
+ }
118
+ })().catch(e => { /* fail-graceful */ });
119
+ " 2>/dev/null || true)
120
+ if [ -n "$OUT_OF_SCOPE" ]; then
121
+ echo "⚠️ Agent OS (ADR-0009 R2-2): post-hoc claim check" >&2
122
+ echo "$OUT_OF_SCOPE" >&2
123
+ echo " Run \`dw agent claims\` to inspect; cooperative trust — proceed with care." >&2
124
+ ISSUES=$((ISSUES + 1))
125
+ fi
126
+ fi
127
+ fi
128
+
70
129
  # Check: sensitive patterns?
71
130
  SENSITIVE=$(git diff --cached 2>/dev/null | grep "^+" | grep -iE '(password|secret|api_key|private_key)[[:space:]]*=[[:space:]]*.{8,}' | grep -v "^+++" | head -3)
72
131
  if [ -n "$SENSITIVE" ]; then
@@ -1,6 +1,7 @@
1
1
  #!/usr/bin/env bash
2
- # Stop hook: warn on uncommitted changes + auto-append handoff to active task tracking.md
3
- # v1.4: auto-handoff (ST-2.5) — append session summary to tracking.md when uncommitted
2
+ # Stop hook: warn on uncommitted changes + auto-handoff + auto-rotate v3 task.md
3
+ # v1.4: auto-handoff (ST-2.5) — append session summary when uncommitted
4
+ # v1.5 (ADR-0008): v3 task.md support + auto-rotate Section 4 > 400 lines via `dw task rotate`
4
5
  # Output via stderr for user visibility. Always exit 0 (non-blocking).
5
6
 
6
7
  PROJECT_DIR="${CLAUDE_PROJECT_DIR:-$(pwd)}"
@@ -22,60 +23,139 @@ else
22
23
  WARNINGS+=("Uncommitted changes:"$'\n'"$CHANGED")
23
24
  fi
24
25
 
25
- # --- Check in-progress tasks (both v1 3-file and v2 2-file formats) ---
26
+ # --- Check in-progress tasks (v1 / v2 / v3 formats) ---
26
27
  TASKS_DIR="$PROJECT_DIR/.dw/tasks"
27
28
  ACTIVE_TASK=""
29
+ ACTIVE_TASK_FORMAT=""
30
+ ACTIVE_TASK_FILE=""
28
31
 
29
32
  if [ -d "$TASKS_DIR" ]; then
33
+ # v3 format (preferred): task.md with frontmatter status In Progress
34
+ while IFS= read -r timeline_file; do
35
+ if grep -qE "^status:[[:space:]]*(In Progress|Blocked)" "$timeline_file" 2>/dev/null; then
36
+ task_name=$(basename "$(dirname "$timeline_file")")
37
+ WARNINGS+=("Task active (v3): $task_name")
38
+ if [ -z "$ACTIVE_TASK" ]; then
39
+ ACTIVE_TASK="$task_name"
40
+ ACTIVE_TASK_FORMAT="v3"
41
+ ACTIVE_TASK_FILE="$timeline_file"
42
+ fi
43
+ fi
44
+ done < <(find "$TASKS_DIR" -maxdepth 3 -name "task.md" -not -path "*/archive/*" 2>/dev/null)
45
+
30
46
  # v1 format: {task}-progress.md with "Trạng thái: In Progress"
31
47
  while IFS= read -r progress_file; do
32
48
  if grep -q "Trạng thái: In Progress" "$progress_file" 2>/dev/null; then
33
49
  task_name=$(basename "$(dirname "$progress_file")")
34
50
  WARNINGS+=("Task in-progress (v1): $task_name")
35
- [ -z "$ACTIVE_TASK" ] && ACTIVE_TASK="$task_name"
51
+ if [ -z "$ACTIVE_TASK" ]; then
52
+ ACTIVE_TASK="$task_name"
53
+ ACTIVE_TASK_FORMAT="v1"
54
+ ACTIVE_TASK_FILE="$progress_file"
55
+ fi
36
56
  fi
37
57
  done < <(find "$TASKS_DIR" -maxdepth 3 -name "*-progress.md" -not -path "*/archive/*" 2>/dev/null)
38
58
 
39
59
  # v2 format: tracking.md with frontmatter status In Progress
40
60
  while IFS= read -r tracking_file; do
61
+ # Skip if same folder already has task.md (v3 takes precedence)
62
+ folder_dir=$(dirname "$tracking_file")
63
+ [ -f "$folder_dir/task.md" ] && continue
41
64
  if grep -qE "^status:.*(In Progress|Code Complete)" "$tracking_file" 2>/dev/null; then
42
- task_name=$(basename "$(dirname "$tracking_file")")
65
+ task_name=$(basename "$folder_dir")
43
66
  WARNINGS+=("Task active (v2): $task_name")
44
- [ -z "$ACTIVE_TASK" ] && ACTIVE_TASK="$task_name"
67
+ if [ -z "$ACTIVE_TASK" ]; then
68
+ ACTIVE_TASK="$task_name"
69
+ ACTIVE_TASK_FORMAT="v2"
70
+ ACTIVE_TASK_FILE="$tracking_file"
71
+ fi
45
72
  fi
46
73
  done < <(find "$TASKS_DIR" -maxdepth 3 -name "tracking.md" -not -path "*/archive/*" 2>/dev/null)
47
74
  fi
48
75
 
49
- # --- Auto-handoff: append snippet to active task's tracking.md if uncommitted + active task ---
50
- if [ "$HAS_UNCOMMITTED" = "1" ] && [ -n "$ACTIVE_TASK" ]; then
51
- TRACKING_FILE="$TASKS_DIR/$ACTIVE_TASK/tracking.md"
52
- if [ -f "$TRACKING_FILE" ]; then
53
- TS=$(date -u +"%Y-%m-%d %H:%M UTC")
54
- MARKER="<!-- dw-auto-handoff -->"
76
+ # --- v3 auto-rotate (Section 4 > 400 lines → timeline-history.md) ---
77
+ # Fire-and-forget; uses local dw CLI if available.
78
+ if [ "$ACTIVE_TASK_FORMAT" = "v3" ] && [ -n "$ACTIVE_TASK" ]; then
79
+ DW_BIN="$PROJECT_DIR/bin/dw.mjs"
80
+ if [ -f "$DW_BIN" ] && command -v node >/dev/null 2>&1; then
81
+ ROTATE_OUTPUT=$(node "$DW_BIN" task rotate "$ACTIVE_TASK" --quiet 2>&1 || true)
82
+ if [ -n "$ROTATE_OUTPUT" ] && echo "$ROTATE_OUTPUT" | grep -q "rotated"; then
83
+ WARNINGS+=("Auto-rotated Section 4 → timeline-history.md ($ACTIVE_TASK)")
84
+ fi
85
+ fi
86
+ fi
87
+
88
+ # --- Auto-handoff: append snippet to active task's tracking/timeline file if uncommitted ---
89
+ if [ "$HAS_UNCOMMITTED" = "1" ] && [ -n "$ACTIVE_TASK_FILE" ]; then
90
+ TS=$(date -u +"%Y-%m-%d %H:%M UTC")
91
+ MARKER="<!-- dw-auto-handoff -->"
55
92
 
56
- # Only append if no handoff snippet added in last 10 minutes (idempotency via marker + timestamp grep)
57
- if ! grep -q "$MARKER.*$TS" "$TRACKING_FILE" 2>/dev/null; then
58
- {
59
- echo ""
60
- echo "$MARKER"
61
- echo "### Auto-handoff $TS"
62
- echo ""
63
- echo "Session ended with uncommitted changes."
64
- echo ""
65
- echo "**Files changed:**"
66
- echo '```'
67
- git -C "$PROJECT_DIR" diff --stat --cached 2>/dev/null
68
- git -C "$PROJECT_DIR" diff --stat 2>/dev/null
69
- echo '```'
70
- echo ""
71
- echo "Next session: commit or continue work. Re-read spec.md + this tracking.md first."
72
- echo ""
73
- } >> "$TRACKING_FILE" 2>/dev/null
74
- WARNINGS+=("Auto-handoff appended to: $TRACKING_FILE")
93
+ # Only append if no handoff snippet added in last 10 minutes (idempotency via marker + timestamp grep)
94
+ if ! grep -q "$MARKER.*$TS" "$ACTIVE_TASK_FILE" 2>/dev/null; then
95
+ if [ "$ACTIVE_TASK_FORMAT" = "v3" ]; then
96
+ READ_FIRST="Re-read this task.md (Section 1 + 3 + 5) first."
97
+ else
98
+ READ_FIRST="Re-read spec.md + this tracking.md first."
75
99
  fi
100
+
101
+ HANDOFF_SNIPPET=$({
102
+ echo ""
103
+ echo "$MARKER"
104
+ echo "### Auto-handoff — $TS"
105
+ echo ""
106
+ echo "Session ended with uncommitted changes."
107
+ echo ""
108
+ echo "**Files changed:**"
109
+ echo '```'
110
+ git -C "$PROJECT_DIR" diff --stat --cached 2>/dev/null
111
+ git -C "$PROJECT_DIR" diff --stat 2>/dev/null
112
+ echo '```'
113
+ echo ""
114
+ echo "Next session: commit or continue work. $READ_FIRST"
115
+ echo ""
116
+ })
117
+
118
+ if [ "$ACTIVE_TASK_FORMAT" = "v3" ]; then
119
+ # v3: insert before Section 5 closing (## 6. Annexes) so handoffs stay in Handoff section
120
+ # Use node for cross-platform reliable section insertion
121
+ if command -v node >/dev/null 2>&1; then
122
+ TMPF=$(mktemp)
123
+ printf '%s' "$HANDOFF_SNIPPET" > "$TMPF"
124
+ node -e "
125
+ const fs = require('fs');
126
+ const file = '$ACTIVE_TASK_FILE';
127
+ const snippet = fs.readFileSync('$TMPF', 'utf8');
128
+ const body = fs.readFileSync(file, 'utf8');
129
+ // Insert right before '## 6. Annexes' (or EOF if not found)
130
+ const sec6 = body.indexOf('## 6. Annexes');
131
+ if (sec6 >= 0) {
132
+ fs.writeFileSync(file, body.slice(0, sec6) + snippet + '\\n' + body.slice(sec6));
133
+ } else {
134
+ // No Section 6 yet — append (rare; only freshly-scaffolded tasks)
135
+ fs.appendFileSync(file, snippet);
136
+ }
137
+ " 2>/dev/null
138
+ rm -f "$TMPF"
139
+ else
140
+ # Fallback: append to EOF (degraded for v3 but still functional)
141
+ printf '%s' "$HANDOFF_SNIPPET" >> "$ACTIVE_TASK_FILE" 2>/dev/null
142
+ fi
143
+ else
144
+ # v1/v2: append to EOF (legacy behavior, unchanged)
145
+ printf '%s' "$HANDOFF_SNIPPET" >> "$ACTIVE_TASK_FILE" 2>/dev/null
146
+ fi
147
+ WARNINGS+=("Auto-handoff appended to: $ACTIVE_TASK_FILE")
76
148
  fi
77
149
  fi
78
150
 
151
+ # --- Nudge dw task show (first-of-session, v3 only) ---
152
+ NUDGE_FILE="$PROJECT_DIR/.dw/cache/.show-nudge-$(date -u +%Y-%m-%d)"
153
+ if [ "$ACTIVE_TASK_FORMAT" = "v3" ] && [ -n "$ACTIVE_TASK" ] && [ ! -f "$NUDGE_FILE" ]; then
154
+ mkdir -p "$PROJECT_DIR/.dw/cache" 2>/dev/null
155
+ touch "$NUDGE_FILE" 2>/dev/null
156
+ WARNINGS+=("Tip: \`dw task show $ACTIVE_TASK\` (terminal) · \`dw task view $ACTIVE_TASK\` (HTML in browser) · \`dw task lint\` (drift check)")
157
+ fi
158
+
79
159
  # --- Print warnings ---
80
160
  if [ ${#WARNINGS[@]} -gt 0 ]; then
81
161
  printf -- "--- dw stop-check ---\n" >&2
@@ -1,37 +1,48 @@
1
- # Commit Standards
2
-
3
- ## Format
4
- ```
5
- <type>(<scope>): <mô tả tiếng Việt hoặc tiếng Anh>
6
-
7
- [Body - chi tiết thay đổi, lý do]
8
- [Blank line]
9
- [Footer - breaking changes, references]
10
-
11
- Co-Authored-By: Claude <noreply@anthropic.com>
12
- ```
13
-
14
- ## Types
15
- | Type | Khi nào dùng |
16
- |------|-------------|
17
- | `feat` | Tính năng mới |
18
- | `fix` | Sửa lỗi |
19
- | `refactor` | Tái cấu trúc, không thay đổi behavior |
20
- | `test` | Thêm/sửa tests |
21
- | `docs` | Tài liệu, comments |
22
- | `chore` | Build, config, dependencies |
23
- | `style` | Format, whitespace (không thay đổi logic) |
24
- | `perf` | Cải thiện performance |
25
-
26
- ## Quy tắc
27
- - Mỗi commit = 1 subtask hoặc 1 đơn vị logic hoàn chỉnh
28
- - tả ngắn <= 72 ký tự
29
- - Dùng thì hiện tại: "thêm", "sửa", "cập nhật" (không phải "đã thêm")
30
- - KHÔNG commit files chứa secrets (.env, credentials, tokens)
31
- - KHÔNG commit console.log/debugger còn sót
32
-
33
- ## Branch Naming
34
- ```
35
- <type>/<task-name>
36
- ```
37
- Ví dụ: `feat/user-auth`, `fix/login-redirect`, `refactor/api-structure`
1
+ # Commit Standards
2
+
3
+ ## Format
4
+
5
+ ```
6
+ <type>(<scope>): <imperative English subject ≤72 chars>
7
+
8
+ [Optional body — explain WHY, wrap at 72 chars]
9
+
10
+ [Optional footer — BREAKING CHANGE: ..., Refs: #123]
11
+ ```
12
+
13
+ **English only.** Use imperative mood: `add user auth`, `fix login redirect`, `update API client` — never `added`, `fixes`, or past tense.
14
+
15
+ **Do not append `Co-Authored-By: Claude` or any AI signature.** Commits are authored by the human who reviewed and shipped them.
16
+
17
+ ## Types
18
+
19
+ | Type | When to use |
20
+ |------|-------------|
21
+ | `feat` | New feature |
22
+ | `fix` | Bug fix |
23
+ | `refactor` | Restructure without behavior change |
24
+ | `test` | Add or update tests |
25
+ | `docs` | Documentation, comments |
26
+ | `chore` | Build, config, dependencies |
27
+ | `style` | Format, whitespace (no logic change) |
28
+ | `perf` | Performance improvement |
29
+
30
+ ## Rules
31
+
32
+ - One commit = one subtask or one complete logical unit
33
+ - Subject ≤72 chars; body wrapped at 72
34
+ - Imperative present tense (`add`, `fix`, `update` — not `added`, `fixed`, `updates`)
35
+ - Never commit secrets (`.env`, credentials, tokens)
36
+ - Never commit leftover `console.log`, `debugger`, etc.
37
+
38
+ ## Branch Naming
39
+
40
+ ```
41
+ <type>/<task-name>
42
+ ```
43
+
44
+ Examples: `feat/user-auth`, `fix/login-redirect`, `refactor/api-structure`
45
+
46
+ ## Localization Override
47
+
48
+ This convention defaults to English to match the global open-source norm. A team that ships only in another language MAY override this rule in their own project by editing this file — but the toolkit itself ships English-default templates.
@@ -18,7 +18,7 @@ Prompt contains `--no-dw` → ignore all dw instructions for that request, work
18
18
  | **Guards** | Block unsafe actions | privacy-block, pre-commit-gate | Non-negotiable safety |
19
19
  | **Surfaces** | Make state visible | ACTIVE.md, project-map, modules | Shared team context |
20
20
  | **Records** | Capture decisions | ADRs in `.dw/decisions/` | Organizational memory |
21
- | **Bridges** | Connect across sessions | auto-handoff, tracking.md | Continuity over time |
21
+ | **Bridges** | Connect across sessions | auto-handoff, task.md, auto-rotate | Continuity over time |
22
22
  | **Tunes** | Behavioral knobs | roles, depth, presets | Team/solo customization |
23
23
 
24
24
  ---
@@ -30,8 +30,8 @@ Assess per task — file count, API changes, git blame:
30
30
  | Scope | Depth | Approach |
31
31
  |-------|-------|----------|
32
32
  | ≤2 files, hotfix | quick | Understand → Execute → Close |
33
- | 3–5 files, new module | standard | spec.md + tracking.md |
34
- | 6+ files, API/DB/security | thorough | Full 2-file + optional reports/ |
33
+ | 3–5 files, new module | standard | task.md (Sections 1-5) |
34
+ | 6+ files, API/DB/security | thorough | Full task.md + Section 6 Annexes + optional Section 7 Debate |
35
35
 
36
36
  Default when unsure: `standard`.
37
37
 
@@ -40,22 +40,56 @@ Default when unsure: `standard`.
40
40
  ## Session Start
41
41
 
42
42
  1. Read `.dw/tasks/ACTIVE.md` — single source of truth for team state
43
- 2. Resume any task with status `In Progress` from its `tracking.md`
43
+ 2. Resume any task with status `In Progress` from its `task.md` (v3) / `tracking.md` (v2)
44
44
  3. Check `.dw/decisions/` for recent ADRs if task touches architecture
45
+ 4. Optional quick scan: `dw task show <name>` for ANSI snapshot
45
46
 
46
47
  ---
47
48
 
48
- ## Task Docs (v2 default — 2 files)
49
+ ## Task Docs (v3 default — 1 file, per ADR-0008)
49
50
 
50
51
  ```
51
52
  .dw/tasks/{task-name}/
52
- ├── spec.md # Intent + plan (stable after approve)
53
- └── tracking.md # Progress + handoff (mutable)
53
+ ├── task.md # canonical SoT: Snapshot + Intent + Tracker + Changelog + Handoff
54
+ ├── timeline.svg # auto-rendered sidecar (v1.6+ via dw-kit-render)
55
+ └── (free-form appendages):
56
+ ├── baseline.md # benchmark snapshots
57
+ ├── experiment-{id}.md # spike notes
58
+ ├── debate-r{N}.md # extended adversarial logs
59
+ └── timeline-history.md # auto-rotated changelog overflow
54
60
  ```
55
61
 
56
- Legacy 3-file (`context + plan + progress`) still supported for older tasks.
62
+ **Section structure** (status lives ONLY in Section 3 drift prevention):
63
+ 1. Snapshot · 2. Intent & Scope · 3. Subtask Tracker · 4. Timeline/Changelog · 5. Handoff & Friction · 6. Annexes · 7. Debate Log (optional thorough)
57
64
 
58
- Templates at `.dw/core/templates/v2/`.
65
+ **Lint default strict** — drift markers (✅🟡 status) in Section 2 → error. Configure via `task.lint: warn | off` in `dw.config.yml`.
66
+
67
+ **CLI:** `dw task new <name>` (scaffold) · `dw task show [name]` (ANSI snapshot) · `dw task lint [name]` (drift + schema check) · `dw task migrate <name>` (v2→v3) · `dw task rotate [name]` (auto Section-4 overflow).
68
+
69
+ **Backward compat:**
70
+ - v2 (`spec.md` + `tracking.md`) read-only — migrate via `dw task migrate <name>`.
71
+ - v1 (3-file `context + plan + progress`) read-only legacy.
72
+
73
+ Templates: `.dw/core/templates/v3/task.md`. Schema: `.dw/core/schemas/task-frontmatter.schema.json` (ajv-validated).
74
+
75
+ ---
76
+
77
+ ## Agent OS (v1.6+, ADR-0009)
78
+
79
+ Multi-agent orchestration protocol. Multiple AI agents (Claude Code / Codex / Gemini / human) work from same `task.md` without conflict.
80
+
81
+ ```
82
+ dw agent claim <task> --subtasks ST-1 --write "src/foo.js" --vendor claude --lease 1h
83
+ dw agent claims # list active
84
+ dw agent conflicts # detect overlaps (exit 1 if dirty)
85
+ dw agent release <claim-id> # clean exit
86
+ ```
87
+
88
+ **Cooperative-only:** protocol catches violations post-hoc via `dw agent conflicts` + `pre-commit-gate`. Not an enforcement system.
89
+
90
+ **Storage:** `.dw/cache/agents/claims/{id}.json` (gitignored ephemeral); `.dw/tasks/{task}/reports/{agent}-{ts}.md` + `events.jsonl` (committed audit).
91
+
92
+ **Workflow:** orchestrator role splits work → agents claim → write → release → reports merged into `task.md` Section 3/4 → orchestrator stops before push/release for human approval.
59
93
 
60
94
  ---
61
95
 
@@ -82,11 +116,13 @@ See `.dw/core/skills-index.md` for complete list with descriptions.
82
116
  ## Commit Format
83
117
 
84
118
  ```
85
- <type>(<scope>): <description ≤72 chars>
119
+ <type>(<scope>): <imperative English subject ≤72 chars>
86
120
  ```
87
121
 
88
122
  Types: `feat` `fix` `refactor` `test` `docs` `chore` `style` `perf`
89
123
 
124
+ English imperative mood (`add`, `fix`, `update` — not past tense or other languages). **Do not append `Co-Authored-By: Claude` or any AI signature.** Full rules: `.claude/rules/commit-standards.md`.
125
+
90
126
  ---
91
127
 
92
128
  ## Hooks
@@ -95,7 +131,7 @@ Types: `feat` `fix` `refactor` `test` `docs` `chore` `style` `perf`
95
131
  |------|---------|
96
132
  | `privacy-block` | Guard — block .env/credentials/keys |
97
133
  | `pre-commit-gate` | Guard — quality check + sensitive scan |
98
- | `stop-check` | Bridge — auto-handoff to tracking.md + uncommitted warning |
134
+ | `stop-check` | Bridge — auto-handoff to task.md (v3) / tracking.md (v2) + auto-rotate Section 4 + uncommitted warning |
99
135
  | `telemetry-log` | Meta — local event log for v1.4 cut decisions |
100
136
 
101
137
  Legacy (deprecated, removal in v2.0 based on telemetry): scout-block, post-write, progress-ping, session-init, safety-guard.
@@ -48,17 +48,20 @@ Nếu không có changes → thông báo "Không có gì để commit."
48
48
 
49
49
  ### 5. Tạo commit message
50
50
 
51
- Nếu có `$ARGUMENTS` → dùng làm tả:
51
+ Nếu có `$ARGUMENTS` → dùng làm subject (rewrite sang English imperative nếu input không phải English):
52
52
  ```
53
- <auto-detect-type>(<auto-detect-scope>): $ARGUMENTS
53
+ <auto-detect-type>(<auto-detect-scope>): <imperative English ≤72 chars>
54
54
 
55
- Co-Authored-By: Claude <noreply@anthropic.com>
55
+ [Optional body — explain WHY in English, wrap at 72]
56
56
  ```
57
57
 
58
+ **KHÔNG append `Co-Authored-By: Claude` hoặc bất kỳ AI signature nào.**
59
+ Convention chi tiết: `.claude/rules/commit-standards.md`.
60
+
58
61
  Nếu KHÔNG có `$ARGUMENTS` → phân tích diff và tạo message tự động:
59
62
  - Detect type từ loại thay đổi (feat/fix/refactor/test/docs/chore)
60
63
  - Detect scope từ files/directories changed
61
- - Viết tả ngắn gọn
64
+ - Subject: imperative English, ≤72 chars (`add X`, `fix Y`, `update Z` — không past tense)
62
65
 
63
66
  ### 6. Thực hiện commit
64
67
  ```bash
@@ -78,7 +78,7 @@ Nếu yes → write file + print:
78
78
  ✓ ADR-{NNNN} created
79
79
  Status: Proposed
80
80
  Next: Review → change status to Accepted when approved
81
- Related task: update tracking.md với reference
81
+ Related task: update task.md (v3) / tracking.md (v2) với reference
82
82
  ```
83
83
 
84
84
  ## Quality Bar
@@ -110,7 +110,8 @@ Trong các case này, đẩy lại user với câu hỏi clarify.
110
110
 
111
111
  ## Super-power: Link related task
112
112
 
113
- Sau khi save ADR, nếu đang trong task folder (check `.dw/tasks/*/tracking.md` reference đến decision này không):
113
+ Sau khi save ADR, nếu đang trong task folder, check task file theo thứ tự ưu tiên:
114
114
 
115
- 1. Append vào `tracking.md` section Changelog: `Referenced: ADR-{NNNN}`
116
- 2. Update `spec.md` frontmatter `related_adr: ADR-{NNNN}` nếu chưa có
115
+ - **v3** (default): `.dw/tasks/*/task.md` append Section 4 Changelog entry: `Referenced: ADR-{NNNN}`; update frontmatter `related_adr: ADR-{NNNN}` nếu chưa có.
116
+ - **v2**: `.dw/tasks/*/tracking.md` append Changelog entry; update spec.md frontmatter `related_adr`.
117
+ - **v1** (legacy): `.dw/tasks/*/*-progress.md` — append changelog