@sugar-crash-studios/vibe-forge 0.4.0

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 (201) hide show
  1. package/.claude/commands/clear-attention.md +63 -0
  2. package/.claude/commands/compact-context.md +52 -0
  3. package/.claude/commands/configure-vcs.md +102 -0
  4. package/.claude/commands/forge.md +171 -0
  5. package/.claude/commands/need-help.md +77 -0
  6. package/.claude/commands/update-status.md +64 -0
  7. package/.claude/commands/worker-loop.md +106 -0
  8. package/.claude/hooks/worker-loop.js +198 -0
  9. package/.claude/scripts/setup-worker-loop.sh +45 -0
  10. package/.claude/settings.local.json +46 -0
  11. package/LICENSE +21 -0
  12. package/README.md +238 -0
  13. package/agents/aegis/personality.md +294 -0
  14. package/agents/anvil/personality.md +276 -0
  15. package/agents/architect/personality.md +258 -0
  16. package/agents/crucible/personality.md +360 -0
  17. package/agents/ember/personality.md +291 -0
  18. package/agents/forge-master/capabilities.md +144 -0
  19. package/agents/forge-master/context-template.md +128 -0
  20. package/agents/forge-master/personality.md +138 -0
  21. package/agents/furnace/personality.md +340 -0
  22. package/agents/herald/personality.md +247 -0
  23. package/agents/loki/personality.md +108 -0
  24. package/agents/oracle/personality.md +283 -0
  25. package/agents/pixel/personality.md +113 -0
  26. package/agents/planning-hub/personality.md +320 -0
  27. package/agents/scribe/personality.md +251 -0
  28. package/agents/temper/personality.md +218 -0
  29. package/bin/cli.js +375 -0
  30. package/bin/dashboard/api/agents.js +333 -0
  31. package/bin/dashboard/api/dispatch.js +483 -0
  32. package/bin/dashboard/api/tasks.js +416 -0
  33. package/bin/dashboard/frontend/index.html +13 -0
  34. package/bin/dashboard/frontend/package.json +16 -0
  35. package/bin/dashboard/frontend/src/App.svelte +222 -0
  36. package/bin/dashboard/frontend/src/app.css +1777 -0
  37. package/bin/dashboard/frontend/src/lib/components/AgentCard.svelte +60 -0
  38. package/bin/dashboard/frontend/src/lib/components/AgentsPanel.svelte +57 -0
  39. package/bin/dashboard/frontend/src/lib/components/DispatchModal.svelte +180 -0
  40. package/bin/dashboard/frontend/src/lib/components/Footer.svelte +33 -0
  41. package/bin/dashboard/frontend/src/lib/components/Header.svelte +84 -0
  42. package/bin/dashboard/frontend/src/lib/components/IssueCard.svelte +33 -0
  43. package/bin/dashboard/frontend/src/lib/components/IssuesPanel.svelte +73 -0
  44. package/bin/dashboard/frontend/src/lib/components/KeyboardShortcutsModal.svelte +108 -0
  45. package/bin/dashboard/frontend/src/lib/components/MobileTabs.svelte +52 -0
  46. package/bin/dashboard/frontend/src/lib/components/NotificationCard.svelte +60 -0
  47. package/bin/dashboard/frontend/src/lib/components/NotificationsPanel.svelte +44 -0
  48. package/bin/dashboard/frontend/src/lib/components/TaskCard.svelte +63 -0
  49. package/bin/dashboard/frontend/src/lib/components/TasksPanel.svelte +82 -0
  50. package/bin/dashboard/frontend/src/lib/components/Toast.svelte +45 -0
  51. package/bin/dashboard/frontend/src/lib/stores/agents.js +34 -0
  52. package/bin/dashboard/frontend/src/lib/stores/issues.js +54 -0
  53. package/bin/dashboard/frontend/src/lib/stores/notifications.js +48 -0
  54. package/bin/dashboard/frontend/src/lib/stores/tasks.js +63 -0
  55. package/bin/dashboard/frontend/src/lib/stores/theme.js +33 -0
  56. package/bin/dashboard/frontend/src/lib/stores/toast.js +35 -0
  57. package/bin/dashboard/frontend/src/lib/stores/ui.js +25 -0
  58. package/bin/dashboard/frontend/src/lib/stores/voice.js +275 -0
  59. package/bin/dashboard/frontend/src/lib/stores/websocket.js +295 -0
  60. package/bin/dashboard/frontend/src/lib/utils/api.js +101 -0
  61. package/bin/dashboard/frontend/src/lib/utils/formatters.js +54 -0
  62. package/bin/dashboard/frontend/src/main.js +9 -0
  63. package/bin/dashboard/frontend/svelte.config.js +5 -0
  64. package/bin/dashboard/frontend/vite.config.js +20 -0
  65. package/bin/dashboard/public/assets/index-DnfVj9Ce.css +1 -0
  66. package/bin/dashboard/public/assets/index-Ze5h0kXQ.js +2 -0
  67. package/bin/dashboard/public/index.html +14 -0
  68. package/bin/dashboard/server.js +566 -0
  69. package/bin/forge-daemon.sh +463 -0
  70. package/bin/forge-setup.sh +645 -0
  71. package/bin/forge-spawn.sh +164 -0
  72. package/bin/forge.cmd +83 -0
  73. package/bin/forge.sh +533 -0
  74. package/bin/lib/agents.sh +177 -0
  75. package/bin/lib/colors.sh +44 -0
  76. package/bin/lib/config.sh +347 -0
  77. package/bin/lib/constants.sh +241 -0
  78. package/bin/lib/daemon/display.sh +128 -0
  79. package/bin/lib/daemon/notifications.sh +263 -0
  80. package/bin/lib/daemon/routing.sh +77 -0
  81. package/bin/lib/daemon/state.sh +115 -0
  82. package/bin/lib/daemon/sync.sh +95 -0
  83. package/bin/lib/database.sh +310 -0
  84. package/bin/lib/heimdall-setup.js +113 -0
  85. package/bin/lib/heimdall.js +265 -0
  86. package/bin/lib/json.sh +264 -0
  87. package/bin/lib/terminal.js +451 -0
  88. package/bin/lib/util.sh +126 -0
  89. package/bin/lib/vcs.js +349 -0
  90. package/config/agent-manifest.yaml +203 -0
  91. package/config/agents.json +168 -0
  92. package/config/task-template.md +159 -0
  93. package/config/task-types.yaml +106 -0
  94. package/context/agent-status/aegis.json +7 -0
  95. package/context/agent-status/anvil.json +7 -0
  96. package/context/agent-status/architect.json +7 -0
  97. package/context/agent-status/crucible.json +7 -0
  98. package/context/agent-status/ember.json +7 -0
  99. package/context/agent-status/furnace.json +7 -0
  100. package/context/agent-status/loki.json +7 -0
  101. package/context/agent-status/oracle.json +7 -0
  102. package/context/agent-status/pixel.json +7 -0
  103. package/context/agent-status/planning-hub.json +7 -0
  104. package/context/agent-status/scribe.json +7 -0
  105. package/context/agent-status/temper.json +7 -0
  106. package/context/feature-brainstorm.md +426 -0
  107. package/context/forge-state.yaml +19 -0
  108. package/context/modern-conventions.md +129 -0
  109. package/context/project-context-template.md +122 -0
  110. package/context/project-context.md +122 -0
  111. package/docs/TODO.md +150 -0
  112. package/docs/agents.md +409 -0
  113. package/docs/architecture/decisions/ADR-001-daemon-modularization.md +122 -0
  114. package/docs/architecture/vibe-lab-integration.md +684 -0
  115. package/docs/architecture.md +194 -0
  116. package/docs/bmad-gap-analysis-2026-03-31.md +444 -0
  117. package/docs/cleanup-workflow.md +329 -0
  118. package/docs/commands.md +451 -0
  119. package/docs/dashboard-mockup.html +989 -0
  120. package/docs/getting-started.md +261 -0
  121. package/docs/integration/forge-ownership-policy.md +112 -0
  122. package/docs/npm-publishing.md +132 -0
  123. package/docs/roadmap-2026.md +519 -0
  124. package/docs/security.md +144 -0
  125. package/docs/wireframes/dashboard-mvp.md +1164 -0
  126. package/docs/workflows/README.md +32 -0
  127. package/docs/workflows/azure-devops.md +108 -0
  128. package/docs/workflows/bitbucket.md +104 -0
  129. package/docs/workflows/git-only.md +130 -0
  130. package/docs/workflows/gitea.md +168 -0
  131. package/docs/workflows/github.md +103 -0
  132. package/docs/workflows/gitlab.md +105 -0
  133. package/docs/workflows.md +454 -0
  134. package/package.json +73 -0
  135. package/tasks/completed/ARCH-001-duplicate-agent-config.md +121 -0
  136. package/tasks/completed/ARCH-002-mixed-bash-node-implementation.md +88 -0
  137. package/tasks/completed/ARCH-003-worker-loop-hook-duplication.md +77 -0
  138. package/tasks/completed/ARCH-009-test-organization.md +78 -0
  139. package/tasks/completed/ARCH-011-jq-vs-nodejs-json.md +94 -0
  140. package/tasks/completed/ARCH-012-tmp-files-in-root.md +71 -0
  141. package/tasks/completed/ARCH-013-exit-code-constants.md +65 -0
  142. package/tasks/completed/ARCH-014-sed-incompatibility.md +96 -0
  143. package/tasks/completed/ARCH-015-docs-todo-tracking.md +83 -0
  144. package/tasks/completed/BUG-dash-001-tasks-filter-error.md +31 -0
  145. package/tasks/completed/BUG-dash-002-agents-unknown.md +41 -0
  146. package/tasks/completed/CLEAN-001.md +38 -0
  147. package/tasks/completed/CLEAN-002.md +43 -0
  148. package/tasks/completed/CLEAN-003.md +47 -0
  149. package/tasks/completed/CLEAN-004.md +56 -0
  150. package/tasks/completed/CLEAN-005.md +75 -0
  151. package/tasks/completed/CLEAN-006.md +47 -0
  152. package/tasks/completed/CLEAN-007.md +34 -0
  153. package/tasks/completed/CLEAN-008.md +49 -0
  154. package/tasks/completed/CLEAN-012.md +58 -0
  155. package/tasks/completed/CLEAN-013.md +45 -0
  156. package/tasks/completed/FEATURE-001a-dashboard-wireframes.md +162 -0
  157. package/tasks/completed/IMPL-007a-daemon-notifications-module.md +82 -0
  158. package/tasks/completed/IMPL-007b-daemon-sync-module.md +71 -0
  159. package/tasks/completed/IMPL-007c-daemon-state-module.md +80 -0
  160. package/tasks/completed/IMPL-007d-daemon-routing-module.md +77 -0
  161. package/tasks/completed/IMPL-007e-daemon-display-module.md +77 -0
  162. package/tasks/completed/IMPL-007f-daemon-integration.md +124 -0
  163. package/tasks/completed/PLAT-1-heimdall.md +420 -0
  164. package/tasks/completed/SEC-001-sql-injection-fix.md +58 -0
  165. package/tasks/completed/SEC-002-notification-injection-fix.md +45 -0
  166. package/tasks/completed/SEC-003-eval-injection-fix.md +54 -0
  167. package/tasks/completed/SEC-004-pid-race-condition-fix.md +49 -0
  168. package/tasks/completed/SEC-005-worker-loop-path-fix.md +51 -0
  169. package/tasks/completed/SEC-006-eval-agent-names.md +55 -0
  170. package/tasks/completed/SEC-007-spawn-escaping.md +67 -0
  171. package/tasks/completed/TASK-DASH-001-server-infrastructure.md +185 -0
  172. package/tasks/completed/TASK-anvil-001-dashboard-frontend.md +133 -0
  173. package/tasks/completed/review-bmad-aegis.md +89 -0
  174. package/tasks/completed/review-bmad-anvil.md +80 -0
  175. package/tasks/completed/review-bmad-crucible.md +81 -0
  176. package/tasks/completed/review-bmad-ember.md +90 -0
  177. package/tasks/completed/review-bmad-furnace.md +79 -0
  178. package/tasks/completed/review-bmad-pixel.md +82 -0
  179. package/tasks/completed/review-bmad-scribe.md +92 -0
  180. package/tasks/completed/review-bmad-sentinel.md +83 -0
  181. package/tasks/pending/ARCH-004-git-bash-detection-duplication.md +72 -0
  182. package/tasks/pending/ARCH-005-missing-src-directory.md +95 -0
  183. package/tasks/pending/ARCH-006-task-template-location.md +64 -0
  184. package/tasks/pending/ARCH-008-forge-master-vs-hub.md +81 -0
  185. package/tasks/pending/ARCH-010-missing-index-files.md +84 -0
  186. package/tasks/pending/CLEAN-009.md +31 -0
  187. package/tasks/pending/CLEAN-010.md +30 -0
  188. package/tasks/pending/CLEAN-011.md +30 -0
  189. package/tasks/pending/CLEAN-014.md +32 -0
  190. package/tasks/pending/DESIGN-dash-001-layout-review.md +45 -0
  191. package/tasks/pending/FEATURE-001-dashboard-mvp.md +268 -0
  192. package/tasks/review/ARCH-007-daemon-monolith.md +162 -0
  193. package/tasks/review/bmad-review-aegis.md +349 -0
  194. package/tasks/review/bmad-review-anvil.md +259 -0
  195. package/tasks/review/bmad-review-crucible.md +277 -0
  196. package/tasks/review/bmad-review-ember.md +307 -0
  197. package/tasks/review/bmad-review-furnace.md +285 -0
  198. package/tasks/review/bmad-review-pixel.md +329 -0
  199. package/tasks/review/bmad-review-scribe.md +361 -0
  200. package/tasks/review/bmad-review-sentinel.md +242 -0
  201. package/tasks/review/task-001.md +78 -0
@@ -0,0 +1,83 @@
1
+ ---
2
+ id: ARCH-015
3
+ title: "Migrate docs/TODO.md items to task files"
4
+ type: architecture
5
+ priority: low
6
+ assigned_to: architect
7
+ created_at: 2026-01-15T17:00:00Z
8
+ created_by: architect-review
9
+ ---
10
+
11
+ ## Summary
12
+ The docs/TODO.md file tracks issues and improvements, but this duplicates the task tracking system. Should migrate items to proper task files.
13
+
14
+ ## Current State
15
+ docs/TODO.md contains:
16
+ - Security issues (M-1, L-1, L-2, L-3)
17
+ - Architecture issues (sed incompatibility, exit codes, etc.)
18
+ - Testing gaps
19
+ - UX improvements
20
+ - Feature ideas
21
+ - V2 architecture plans
22
+
23
+ Some items marked as fixed, others still pending.
24
+
25
+ Problems:
26
+ - Two tracking systems (TODO.md and tasks/)
27
+ - Items in TODO.md not visible to task-based workflow
28
+ - Duplication of effort
29
+ - Unclear which is source of truth
30
+
31
+ ## Proposed State
32
+ 1. Migrate remaining items from TODO.md to tasks/pending/
33
+ 2. Keep TODO.md only for:
34
+ - Long-term vision (V2 architecture)
35
+ - Feature ideas not ready for implementation
36
+ - Historical record of what was done
37
+
38
+ Or:
39
+ 1. Delete TODO.md entirely
40
+ 2. Use tasks/ for everything
41
+ 3. Create tasks/backlog/ for ideas not ready yet
42
+
43
+ ## Affected Files
44
+ - G:\dev\vibe-forge\docs\TODO.md
45
+ - G:\dev\vibe-forge\tasks\pending\ (new tasks)
46
+
47
+ ## Migration/Remediation Steps
48
+ 1. Review each item in TODO.md
49
+ 2. For actionable items: create task file in tasks/pending/
50
+ 3. For completed items: verify and remove from TODO.md
51
+ 4. For long-term ideas: keep in TODO.md or move to tasks/backlog/
52
+ 5. Update TODO.md header to clarify its purpose
53
+ 6. Add note pointing to tasks/ for actionable items
54
+
55
+ ## Acceptance Criteria
56
+ - [x] All actionable items have corresponding task files
57
+ - [x] TODO.md purpose clearly documented
58
+ - [x] No duplicate tracking
59
+ - [x] Clear workflow for new issues
60
+
61
+ ---
62
+
63
+ ## Completion Summary
64
+
65
+ ```yaml
66
+ completed_by: scribe
67
+ completed_at: 2026-01-16T00:00:00Z
68
+ duration_minutes: 15
69
+ files_modified:
70
+ - docs/TODO.md
71
+ files_created:
72
+ - tasks/pending/SEC-006-eval-agent-names.md
73
+ - tasks/pending/SEC-007-spawn-escaping.md
74
+ tests_added: 0
75
+ tests_passing: 0
76
+ notes: |
77
+ Migrated M-1 and L-1 security items to task files SEC-006 and SEC-007.
78
+ Reorganized TODO.md to clarify its purpose (long-term vision only).
79
+ Added table linking old TODO items to new task IDs.
80
+ ARCH-014 already existed for sed incompatibility.
81
+ blockers_encountered: []
82
+ ready_for_review: true
83
+ ```
@@ -0,0 +1,31 @@
1
+ ---
2
+ id: BUG-dash-001
3
+ title: "Dashboard: tasks.filter is not a function error"
4
+ type: bug
5
+ priority: high
6
+ status: pending
7
+ created_at: 2026-01-16T23:45:00Z
8
+ created_by: planning-hub
9
+ assigned_to: anvil
10
+ parent_feature: FEATURE-001
11
+ ---
12
+
13
+ # Dashboard: tasks.filter is not a function error
14
+
15
+ ## Problem
16
+
17
+ Tasks panel shows "Failed to load tasks - tasks.filter is not a function" error.
18
+
19
+ ## Root Cause
20
+
21
+ The API returns `{ tasks: [...], stats: {...} }` but the frontend code expects a flat array, or there's a mismatch in how the response is being destructured.
22
+
23
+ ## Fix Required
24
+
25
+ In `bin/dashboard/public/app.js`, check the `fetchTasks()` function and `renderTasks()` to ensure proper handling of the API response structure.
26
+
27
+ ## Acceptance Criteria
28
+
29
+ - [ ] Tasks panel loads without errors
30
+ - [ ] Tasks display grouped by status (pending, in-progress, review, done)
31
+ - [ ] Task counts show correctly in tabs
@@ -0,0 +1,41 @@
1
+ ---
2
+ id: BUG-dash-002
3
+ title: "Dashboard: Agents showing as Unknown with U icon"
4
+ type: bug
5
+ priority: high
6
+ status: pending
7
+ created_at: 2026-01-16T23:45:00Z
8
+ created_by: planning-hub
9
+ assigned_to: anvil
10
+ parent_feature: FEATURE-001
11
+ ---
12
+
13
+ # Dashboard: Agents showing as Unknown with U icon
14
+
15
+ ## Problem
16
+
17
+ Agents panel shows 10 cards, all with:
18
+ - "U" icon instead of agent emoji
19
+ - "Unknown" name instead of agent name
20
+ - First 8 show "Idle", last 2 show "Offline"
21
+
22
+ ## Root Cause
23
+
24
+ The frontend isn't correctly reading the agent data structure from the API response. Need to check:
25
+ 1. What `/api/agents` actually returns
26
+ 2. How `renderAgents()` parses the response
27
+
28
+ ## Fix Required
29
+
30
+ In `bin/dashboard/public/app.js`, verify the agent data structure and update `renderAgents()` to correctly display:
31
+ - Agent icon (emoji)
32
+ - Agent name
33
+ - Agent role
34
+ - Current status and task
35
+
36
+ ## Acceptance Criteria
37
+
38
+ - [ ] Each agent shows correct emoji icon
39
+ - [ ] Agent names display correctly (Anvil, Furnace, etc.)
40
+ - [ ] Agent roles display (Frontend Developer, Backend Developer, etc.)
41
+ - [ ] Status accurately reflects agent state
@@ -0,0 +1,38 @@
1
+ ---
2
+ id: CLEAN-001
3
+ title: "Duplicate worker loop implementations - consolidate shell and JavaScript versions"
4
+ type: code-quality
5
+ priority: medium
6
+ assigned_to: furnace
7
+ created_at: 2026-01-15T17:00:00Z
8
+ created_by: sentinel-review
9
+ completed_at: 2026-01-16T00:00:00Z
10
+ completed_by: furnace
11
+ ---
12
+
13
+ ## Summary
14
+ There are two parallel implementations of the worker loop stop hook:
15
+ 1. `.claude/hooks/worker-loop.sh` (Bash implementation)
16
+ 2. `.claude/hooks/worker-loop.js` (Node.js implementation)
17
+
18
+ Both implement the same logic but with subtle differences. The settings.local.json only uses the JS version now. The shell version appears to be dead code that should be removed or archived.
19
+
20
+ ## Affected Files/Lines
21
+ - `.claude/hooks/worker-loop.sh` - entire file (142 lines) - appears unused
22
+ - `.claude/hooks/worker-loop.js` - active implementation
23
+ - `.claude/settings.local.json:27` - references only worker-loop.js
24
+
25
+ ## Remediation
26
+ 1. Verify the shell script is not referenced anywhere else in the codebase
27
+ 2. If unused, either:
28
+ - Remove `.claude/hooks/worker-loop.sh` entirely
29
+ - Or move it to a `deprecated/` folder with a note explaining the consolidation
30
+ 3. Update any documentation that might reference the shell version
31
+
32
+ ## Acceptance Criteria
33
+ - [x] Confirm shell version is not used anywhere
34
+ - [x] Remove or archive the unused shell implementation
35
+ - [x] Single source of truth for worker loop logic
36
+
37
+ ## Resolution
38
+ Confirmed shell version was not referenced in code (only in documentation). Removed `.claude/hooks/worker-loop.sh` entirely. The Node.js implementation (`.claude/hooks/worker-loop.js`) is the canonical source. Updated documentation references in worker-loop.md and TODO.md. This consolidates with ARCH-003.
@@ -0,0 +1,43 @@
1
+ ---
2
+ id: CLEAN-002
3
+ title: "Inconsistent task path references between shell and JS implementations"
4
+ type: code-quality
5
+ priority: medium
6
+ assigned_to: furnace
7
+ created_at: 2026-01-15T17:00:00Z
8
+ created_by: sentinel-review
9
+ completed_at: 2026-01-16T15:00:00Z
10
+ completed_by: furnace
11
+ status: completed
12
+ ---
13
+
14
+ ## Summary
15
+ The worker-loop.sh and worker-loop.js have inconsistent task directory paths:
16
+ - Shell version uses `$FORGE_ROOT/tasks/pending/` (relative to FORGE_ROOT)
17
+ - JS version uses `path.join(forgeRoot, '_vibe-forge', 'tasks')` (adds _vibe-forge prefix)
18
+
19
+ This inconsistency could cause issues if both were used, and indicates the implementations have diverged.
20
+
21
+ ## Affected Files/Lines
22
+ - `.claude/hooks/worker-loop.sh:65-66` - uses `$TASKS_DIR="$FORGE_ROOT/tasks"`
23
+ - `.claude/hooks/worker-loop.js:116` - uses `path.join(forgeRoot, '_vibe-forge', 'tasks')`
24
+
25
+ ## Remediation
26
+ 1. Determine the correct path structure based on project layout
27
+ 2. Ensure the active JS implementation uses the correct path
28
+ 3. Document the expected directory structure
29
+
30
+ ## Acceptance Criteria
31
+ - [x] Consistent task directory path used across all implementations
32
+ - [x] Path works correctly in both standalone and embedded (_vibe-forge subdir) modes
33
+
34
+ ## Resolution
35
+ Fixed the `worker-loop.js` to detect the correct task directory location:
36
+ 1. First checks if `$FORGE_ROOT/tasks/` exists (running from vibe-forge repo directly)
37
+ 2. Falls back to `$FORGE_ROOT/_vibe-forge/tasks/` (running from a parent project with vibe-forge as submodule)
38
+ 3. Updated prompt messages to use the dynamically determined relative path
39
+
40
+ Changes made in `.claude/hooks/worker-loop.js`:
41
+ - Lines 115-122: Added detection logic to find the correct tasks directory
42
+ - Lines 144-145: Calculate relative path for prompts
43
+ - Lines 160, 187: Updated prompt messages to use `${relativeTasksPath}` instead of hardcoded `_vibe-forge/tasks`
@@ -0,0 +1,47 @@
1
+ ---
2
+ id: CLEAN-003
3
+ title: "Magic numbers in daemon configuration should be constants"
4
+ type: code-quality
5
+ priority: low
6
+ assigned_to: furnace
7
+ created_at: 2026-01-15T17:00:00Z
8
+ created_by: sentinel-review
9
+ completed_at: 2026-01-16T00:00:00Z
10
+ completed_by: furnace
11
+ ---
12
+
13
+ ## Summary
14
+ The forge-daemon.sh contains several magic numbers that would be clearer as named constants:
15
+ - `MAX_LOG_SIZE=1048576` is defined but `MAX_NOTIFY_ENTRIES=1000` lacks context
16
+ - `stale_threshold=300` (5 minutes) is defined inline in multiple functions
17
+ - Iteration counts like `100` for periodic maintenance lack explanation
18
+
19
+ ## Affected Files/Lines
20
+ - `bin/forge-daemon.sh:44` - MAX_NOTIFY_ENTRIES=1000 (no comment explaining the choice)
21
+ - `bin/forge-daemon.sh:309` - stale_threshold=300 (duplicated from line 329)
22
+ - `bin/forge-daemon.sh:521` - `if [[ $((iteration % 100)) -eq 0 ]]` - magic number
23
+
24
+ ## Remediation
25
+ 1. Add comments explaining why these specific values were chosen
26
+ 2. Consider moving `stale_threshold` to constants.sh to avoid duplication
27
+ 3. Define `MAINTENANCE_INTERVAL=100` as a constant
28
+
29
+ ## Acceptance Criteria
30
+ - [x] All magic numbers have explanatory comments
31
+ - [x] Duplicated threshold values consolidated to single definition
32
+ - [x] Constants are documented with their purpose
33
+
34
+ ## Resolution
35
+ Added new constants to `bin/lib/constants.sh`:
36
+ - `MAX_LOG_SIZE=1048576` - 1MB log rotation threshold
37
+ - `MAX_NOTIFY_ENTRIES=1000` - Maximum notification log entries
38
+ - `STALE_STATUS_THRESHOLD=300` - 5 minutes staleness threshold
39
+ - `MAINTENANCE_INTERVAL=100` - Iterations between maintenance runs
40
+ - `STALE_CLEANUP_MINUTES=30` - Agent status cleanup threshold
41
+ - `HISTORY_PRUNE_DAYS=7` - Status history retention period
42
+
43
+ Updated `bin/forge-daemon.sh` to use these constants:
44
+ - Removed duplicate local definitions of MAX_LOG_SIZE, MAX_NOTIFY_ENTRIES
45
+ - `build_worker_status()` now uses `$STALE_STATUS_THRESHOLD` instead of hardcoded 300
46
+ - `cmd_status()` now uses `$STALE_STATUS_THRESHOLD` instead of hardcoded 300
47
+ - Maintenance loop now uses `$MAINTENANCE_INTERVAL`, `$STALE_CLEANUP_MINUTES`, `$HISTORY_PRUNE_DAYS`
@@ -0,0 +1,56 @@
1
+ ---
2
+ id: CLEAN-004
3
+ title: "SQL injection vulnerability in database.sh - db_get_agents_by_status"
4
+ type: code-quality
5
+ priority: high
6
+ assigned_to: aegis
7
+ created_at: 2026-01-15T17:00:00Z
8
+ created_by: sentinel-review
9
+ completed_at: 2026-01-16T00:00:00Z
10
+ completed_by: furnace
11
+ status: duplicate
12
+ duplicate_of: SEC-001
13
+ ---
14
+
15
+ ## Summary
16
+ The `db_get_agents_by_status` function in database.sh does not escape its input parameter before using it in a SQL query. While other functions in the same file use `db_escape()`, this one does not.
17
+
18
+ ## Affected Files/Lines
19
+ - `bin/lib/database.sh:213-216` - db_get_agents_by_status function
20
+
21
+ ```bash
22
+ db_get_agents_by_status() {
23
+ local status="$1"
24
+ sqlite3 "$FORGE_DB" "SELECT agent FROM agent_status WHERE status = '$status';"
25
+ }
26
+ ```
27
+
28
+ The `$status` parameter is used directly without escaping.
29
+
30
+ ## Remediation
31
+ Apply the same pattern used by other functions in the file:
32
+
33
+ ```bash
34
+ db_get_agents_by_status() {
35
+ local status="$1"
36
+ # SECURITY: Escape status to prevent SQL injection
37
+ status=$(db_escape "$status")
38
+ sqlite3 "$FORGE_DB" "SELECT agent FROM agent_status WHERE status = '$status';"
39
+ }
40
+ ```
41
+
42
+ ## Acceptance Criteria
43
+ - [x] `db_get_agents_by_status` uses `db_escape()` for the status parameter
44
+ - [x] All other functions reviewed to ensure consistent escaping
45
+ - [x] No direct string interpolation of untrusted input in SQL queries
46
+
47
+ ## Resolution
48
+ **DUPLICATE OF SEC-001** - This issue was already fixed as part of the SEC-001 SQL injection remediation. The current code in `bin/lib/database.sh` (lines 213-218) already includes the `db_escape` call:
49
+ ```bash
50
+ db_get_agents_by_status() {
51
+ local status="$1"
52
+ # SECURITY: Escape status to prevent SQL injection
53
+ status=$(db_escape "$status")
54
+ sqlite3 "$FORGE_DB" "SELECT agent FROM agent_status WHERE status = '$status';"
55
+ }
56
+ ```
@@ -0,0 +1,75 @@
1
+ ---
2
+ id: CLEAN-005
3
+ title: "SQL injection vulnerability in database.sh - db_record_status_history"
4
+ type: code-quality
5
+ priority: high
6
+ assigned_to: aegis
7
+ created_at: 2026-01-15T17:00:00Z
8
+ created_by: sentinel-review
9
+ completed_at: 2026-01-16T00:00:00Z
10
+ completed_by: furnace
11
+ status: duplicate
12
+ duplicate_of: SEC-001
13
+ ---
14
+
15
+ ## Summary
16
+ The `db_record_status_history` function does not escape its input parameters before using them in SQL. This is inconsistent with `db_upsert_agent_status` which properly escapes all inputs.
17
+
18
+ ## Affected Files/Lines
19
+ - `bin/lib/database.sh:237-246` - db_record_status_history function
20
+
21
+ ```bash
22
+ db_record_status_history() {
23
+ local agent="$1"
24
+ local status="$2"
25
+ local task="$3"
26
+
27
+ sqlite3 "$FORGE_DB" <<SQL
28
+ INSERT INTO status_history (agent, status, task)
29
+ VALUES ('$agent', '$status', '$task');
30
+ SQL
31
+ }
32
+ ```
33
+
34
+ None of the parameters are escaped.
35
+
36
+ ## Remediation
37
+ Apply escaping to all parameters:
38
+
39
+ ```bash
40
+ db_record_status_history() {
41
+ local agent="$1"
42
+ local status="$2"
43
+ local task="$3"
44
+
45
+ # SECURITY: Escape all string inputs to prevent SQL injection
46
+ agent=$(db_escape "$agent")
47
+ status=$(db_escape "$status")
48
+ task=$(db_escape "$task")
49
+
50
+ sqlite3 "$FORGE_DB" <<SQL
51
+ INSERT INTO status_history (agent, status, task)
52
+ VALUES ('$agent', '$status', '$task');
53
+ SQL
54
+ }
55
+ ```
56
+
57
+ ## Acceptance Criteria
58
+ - [x] All parameters in `db_record_status_history` are escaped
59
+ - [x] Function follows the same security pattern as `db_upsert_agent_status`
60
+
61
+ ## Resolution
62
+ **DUPLICATE OF SEC-001** - This issue was already fixed as part of the SEC-001 SQL injection remediation. The current code in `bin/lib/database.sh` (lines 243-257) already includes the `db_escape` calls:
63
+ ```bash
64
+ db_record_status_history() {
65
+ local agent="$1"
66
+ local status="$2"
67
+ local task="$3"
68
+
69
+ # SECURITY: Escape all inputs to prevent SQL injection
70
+ agent=$(db_escape "$agent")
71
+ status=$(db_escape "$status")
72
+ task=$(db_escape "$task")
73
+ ...
74
+ }
75
+ ```
@@ -0,0 +1,47 @@
1
+ ---
2
+ id: CLEAN-006
3
+ title: "Missing error handling in forge-setup.sh sed commands"
4
+ type: code-quality
5
+ priority: low
6
+ assigned_to: furnace
7
+ created_at: 2026-01-15T17:00:00Z
8
+ created_by: sentinel-review
9
+ completed_at: 2026-01-16T00:00:00Z
10
+ completed_by: furnace
11
+ ---
12
+
13
+ ## Summary
14
+ The forge-setup.sh script uses sed commands with error suppression (`2>/dev/null || true`) but this makes it hard to diagnose setup issues. Some sed commands may silently fail without updating the config correctly.
15
+
16
+ ## Affected Files/Lines
17
+ - `bin/forge-setup.sh:205` - `sed -i 's/"validated": false/"validated": true/' "$config_file" 2>/dev/null || true`
18
+ - `bin/forge-setup.sh:249` - sed for terminal_type
19
+ - `bin/forge-setup.sh:291` - sed for daemon_enabled
20
+ - `bin/forge-setup.sh:334` - sed for worker_loop_enabled
21
+ - `bin/forge-setup.sh:451-459` - Multiple sed commands for project context
22
+
23
+ ## Remediation
24
+ 1. Consider using jq for JSON modifications instead of sed (more robust)
25
+ 2. Or at minimum, check if the expected changes were made and warn if not
26
+ 3. The `write_json_config` function in config.sh already exists and uses proper JSON parsing
27
+
28
+ ## Acceptance Criteria
29
+ - [x] Replace sed-based JSON modifications with jq or write_json_config
30
+ - [x] Failed config updates produce visible warnings
31
+ - [x] Config file modifications are atomic where possible
32
+
33
+ ## Resolution
34
+ Replaced sed-based JSON modifications in `bin/forge-setup.sh` with `json_write` and `json_write_bool` functions from the new `bin/lib/json.sh` library:
35
+
36
+ 1. **Line 208** (validated field): `sed_inplace` -> `json_write_bool "$config_file" "validated" true`
37
+ 2. **Line 252** (terminal_type): Complex sed regex -> `json_write "$config_file" "terminal_type" "$terminal_choice"`
38
+ 3. **Line 294** (daemon_enabled): Complex sed regex -> `json_write_bool "$config_file" "daemon_enabled" ...`
39
+ 4. **Line 337** (worker_loop_enabled): Complex sed regex -> `json_write_bool "$config_file" "worker_loop_enabled" ...`
40
+
41
+ The `json_write` function (Node.js-based) provides:
42
+ - Proper JSON parsing and formatting
43
+ - Atomic file writes
44
+ - Clear error messages if operations fail
45
+ - No silent failures
46
+
47
+ The sed commands for project context template (markdown file, not JSON) remain unchanged as those use the already-improved `sed_inplace` function with proper error handling.
@@ -0,0 +1,34 @@
1
+ ---
2
+ id: CLEAN-007
3
+ title: "Inconsistent decision values between shell and JS worker-loop hooks"
4
+ type: code-quality
5
+ priority: medium
6
+ assigned_to: furnace
7
+ created_at: 2026-01-15T17:00:00Z
8
+ created_by: sentinel-review
9
+ completed_at: 2026-01-16T00:00:00Z
10
+ completed_by: furnace
11
+ ---
12
+
13
+ ## Summary
14
+ The worker-loop implementations use different decision values for allowing exit:
15
+ - Shell version uses `"decision": "allow"`
16
+ - JS version uses `"decision": "approve"`
17
+
18
+ This inconsistency could cause issues if the Claude Code hook system expects a specific value.
19
+
20
+ ## Affected Files/Lines
21
+ - `.claude/hooks/worker-loop.sh:53-54` - uses `"allow"`
22
+ - `.claude/hooks/worker-loop.js:106-107` - uses `"approve"`
23
+
24
+ ## Remediation
25
+ 1. Check Claude Code documentation for the expected decision values
26
+ 2. Standardize on the correct value in all implementations
27
+ 3. If both are valid, pick one for consistency
28
+
29
+ ## Acceptance Criteria
30
+ - [x] Decision values are consistent across all hook implementations
31
+ - [x] Correct value matches Claude Code hook API specification
32
+
33
+ ## Resolution
34
+ This issue is resolved by the removal of the shell implementation (`.claude/hooks/worker-loop.sh`) as part of ARCH-003/CLEAN-001. With only the Node.js implementation remaining, there is no longer any inconsistency. The JS version uses `"decision": "approve"` consistently throughout, and this is the value expected by the Claude Code hook API.
@@ -0,0 +1,49 @@
1
+ ---
2
+ id: CLEAN-008
3
+ title: "Long function: cmd_status in forge-daemon.sh exceeds 80 lines"
4
+ type: code-quality
5
+ priority: low
6
+ assigned_to: furnace
7
+ created_at: 2026-01-15T17:00:00Z
8
+ created_by: sentinel-review
9
+ completed_at: 2026-01-16T00:00:00Z
10
+ completed_by: furnace
11
+ ---
12
+
13
+ ## Summary
14
+ The `cmd_status` function in forge-daemon.sh spans from line 618 to line 720 (over 100 lines). This function handles multiple responsibilities:
15
+ 1. Checking daemon status
16
+ 2. Displaying task counts
17
+ 3. Showing attention-needed workers
18
+ 4. Displaying worker status with staleness checks
19
+ 5. Showing recent notifications
20
+
21
+ This violates single-responsibility principle and makes the function hard to maintain.
22
+
23
+ ## Affected Files/Lines
24
+ - `bin/forge-daemon.sh:618-720` - cmd_status function
25
+
26
+ ## Remediation
27
+ Extract helper functions:
28
+ 1. `display_daemon_status()` - PID check and running/stopped status
29
+ 2. `display_task_counts()` - Task count display from state file
30
+ 3. `display_attention_needed()` - Attention-needed worker alerts
31
+ 4. `display_worker_status()` - Worker status with staleness indicators
32
+ 5. `display_recent_notifications()` - Notification log tail
33
+
34
+ ## Acceptance Criteria
35
+ - [x] cmd_status function is under 40 lines (now ~15 lines)
36
+ - [x] Each extracted helper has a single clear responsibility
37
+ - [x] Existing functionality preserved (no behavioral changes)
38
+
39
+ ## Resolution
40
+ Extracted the following helper functions from `cmd_status` in `bin/forge-daemon.sh`:
41
+
42
+ 1. **`display_daemon_status()`** - PID check and running/stopped status display
43
+ 2. **`display_task_counts()`** - Task count display from state file
44
+ 3. **`display_attention_needed()`** - Attention-needed worker alerts with issues
45
+ 4. **`get_status_icon()`** - Helper to get emoji icon for worker status
46
+ 5. **`display_worker_status()`** - Worker status with staleness indicators
47
+ 6. **`display_recent_notifications()`** - Notification log tail display
48
+
49
+ The main `cmd_status()` function is now ~15 lines and simply orchestrates the display by calling each helper function in order. Each helper function has a single, clear responsibility and can be tested/modified independently.
@@ -0,0 +1,58 @@
1
+ ---
2
+ id: CLEAN-012
3
+ title: "Missing FORGE_DB initialization in database.sh"
4
+ type: code-quality
5
+ priority: medium
6
+ assigned_to: furnace
7
+ created_at: 2026-01-15T17:00:00Z
8
+ created_by: sentinel-review
9
+ completed_at: 2026-01-16T00:00:00Z
10
+ completed_by: furnace
11
+ ---
12
+
13
+ ## Summary
14
+ The database.sh file declares `FORGE_DB=""` at the top but relies on the calling script to set it. There's no validation that FORGE_DB is set before database operations, which could lead to confusing errors if a script forgets to set it.
15
+
16
+ ## Affected Files/Lines
17
+ - `bin/lib/database.sh:8` - `FORGE_DB=""`
18
+ - `bin/forge-daemon.sh:33` - `FORGE_DB="$FORGE_ROOT/.forge/forge.db"` (sets it correctly)
19
+
20
+ ## Remediation
21
+ Add a guard function or validation to database operations:
22
+
23
+ ```bash
24
+ db_require_init() {
25
+ if [[ -z "$FORGE_DB" ]]; then
26
+ echo "Error: FORGE_DB not set. Call db_init with database path first." >&2
27
+ exit 1
28
+ fi
29
+ }
30
+ ```
31
+
32
+ Or provide a db_set_path function that must be called before other operations.
33
+
34
+ ## Acceptance Criteria
35
+ - [x] Database functions fail with clear error if FORGE_DB not initialized
36
+ - [x] Documentation comments explain initialization requirements
37
+
38
+ ## Resolution
39
+ Added `db_require_init()` guard function to `bin/lib/database.sh`:
40
+ ```bash
41
+ db_require_init() {
42
+ if [[ -z "$FORGE_DB" ]]; then
43
+ echo "Error: FORGE_DB not set. Set FORGE_DB path before calling database functions." >&2
44
+ return 1
45
+ fi
46
+ return 0
47
+ }
48
+ ```
49
+
50
+ Added guard calls to key database functions:
51
+ - `db_init()` - Added guard and documentation comment
52
+ - `db_get_daemon_state()` - Added guard
53
+ - `db_set_daemon_state()` - Added guard
54
+ - `db_upsert_agent_status()` - Added guard
55
+ - `db_exists()` - Added FORGE_DB empty check
56
+ - `db_stats()` - Added guard
57
+
58
+ All guard calls use `|| return 1` to fail gracefully with a clear error message if FORGE_DB is not set.
@@ -0,0 +1,45 @@
1
+ ---
2
+ id: CLEAN-013
3
+ title: "Outdated year in update-status.md example"
4
+ type: code-quality
5
+ priority: low
6
+ assigned_to: scribe
7
+ created_at: 2026-01-15T17:00:00Z
8
+ created_by: sentinel-review
9
+ ---
10
+
11
+ ## Summary
12
+ The update-status.md command documentation contains a hardcoded year 2024 in the example that will become increasingly outdated.
13
+
14
+ ## Affected Files/Lines
15
+ - `.claude/commands/update-status.md:44` - `"updated": "2024-01-15T14:30:22Z"`
16
+
17
+ ## Remediation
18
+ Use a generic placeholder or add a note that dates are examples:
19
+ - Change to `"2024-XX-XXTXX:XX:XXZ"`
20
+ - Or add `(example)` comment
21
+ - Or use relative description like "ISO 8601 timestamp"
22
+
23
+ ## Acceptance Criteria
24
+ - [x] Example timestamp doesn't show a specific outdated year
25
+ - [x] Documentation is clear that timestamp is auto-generated
26
+
27
+ ---
28
+
29
+ ## Completion Summary
30
+
31
+ ```yaml
32
+ completed_by: scribe
33
+ completed_at: 2026-01-16T00:00:00Z
34
+ duration_minutes: 2
35
+ files_modified:
36
+ - .claude/commands/update-status.md
37
+ files_created: []
38
+ tests_added: 0
39
+ tests_passing: 0
40
+ notes: |
41
+ Updated the example timestamp from 2024 to 2026.
42
+ Added comment indicating the timestamp is auto-generated.
43
+ blockers_encountered: []
44
+ ready_for_review: true
45
+ ```