reflectt-node 0.1.4 → 0.1.5

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 (95) hide show
  1. package/README.md +60 -151
  2. package/dist/alert-preflight.d.ts +28 -0
  3. package/dist/alert-preflight.d.ts.map +1 -1
  4. package/dist/alert-preflight.js +178 -0
  5. package/dist/alert-preflight.js.map +1 -1
  6. package/dist/boardHealthWorker.d.ts.map +1 -1
  7. package/dist/boardHealthWorker.js +25 -12
  8. package/dist/boardHealthWorker.js.map +1 -1
  9. package/dist/chat-approval-detector.d.ts.map +1 -1
  10. package/dist/chat-approval-detector.js +29 -11
  11. package/dist/chat-approval-detector.js.map +1 -1
  12. package/dist/chat.d.ts +1 -0
  13. package/dist/chat.d.ts.map +1 -1
  14. package/dist/chat.js +14 -3
  15. package/dist/chat.js.map +1 -1
  16. package/dist/cli.js +187 -22
  17. package/dist/cli.js.map +1 -1
  18. package/dist/cloud.d.ts +28 -1
  19. package/dist/cloud.d.ts.map +1 -1
  20. package/dist/cloud.js +55 -20
  21. package/dist/cloud.js.map +1 -1
  22. package/dist/compliance-detector.d.ts +42 -0
  23. package/dist/compliance-detector.d.ts.map +1 -0
  24. package/dist/compliance-detector.js +286 -0
  25. package/dist/compliance-detector.js.map +1 -0
  26. package/dist/continuity-loop.d.ts.map +1 -1
  27. package/dist/continuity-loop.js +7 -3
  28. package/dist/continuity-loop.js.map +1 -1
  29. package/dist/dashboard.d.ts +6 -2
  30. package/dist/dashboard.d.ts.map +1 -1
  31. package/dist/dashboard.js +55 -26
  32. package/dist/dashboard.js.map +1 -1
  33. package/dist/doctor.d.ts.map +1 -1
  34. package/dist/doctor.js +17 -6
  35. package/dist/doctor.js.map +1 -1
  36. package/dist/executionSweeper.d.ts.map +1 -1
  37. package/dist/executionSweeper.js +12 -0
  38. package/dist/executionSweeper.js.map +1 -1
  39. package/dist/health.d.ts.map +1 -1
  40. package/dist/health.js +30 -7
  41. package/dist/health.js.map +1 -1
  42. package/dist/hostConnectGuard.d.ts +25 -0
  43. package/dist/hostConnectGuard.d.ts.map +1 -0
  44. package/dist/hostConnectGuard.js +27 -0
  45. package/dist/hostConnectGuard.js.map +1 -0
  46. package/dist/index.js +144 -29
  47. package/dist/index.js.map +1 -1
  48. package/dist/insight-task-bridge.d.ts +1 -1
  49. package/dist/insight-task-bridge.d.ts.map +1 -1
  50. package/dist/insight-task-bridge.js +6 -3
  51. package/dist/insight-task-bridge.js.map +1 -1
  52. package/dist/mcp.js +6 -6
  53. package/dist/mcp.js.map +1 -1
  54. package/dist/notificationDedupeGuard.d.ts +33 -0
  55. package/dist/notificationDedupeGuard.d.ts.map +1 -0
  56. package/dist/notificationDedupeGuard.js +88 -0
  57. package/dist/notificationDedupeGuard.js.map +1 -0
  58. package/dist/policy.d.ts +1 -1
  59. package/dist/policy.d.ts.map +1 -1
  60. package/dist/policy.js +3 -1
  61. package/dist/policy.js.map +1 -1
  62. package/dist/reflection-automation.d.ts.map +1 -1
  63. package/dist/reflection-automation.js +38 -0
  64. package/dist/reflection-automation.js.map +1 -1
  65. package/dist/request-tracker.d.ts +6 -0
  66. package/dist/request-tracker.d.ts.map +1 -1
  67. package/dist/request-tracker.js +31 -12
  68. package/dist/request-tracker.js.map +1 -1
  69. package/dist/server.d.ts.map +1 -1
  70. package/dist/server.js +242 -57
  71. package/dist/server.js.map +1 -1
  72. package/dist/service-probe.d.ts.map +1 -1
  73. package/dist/service-probe.js +39 -2
  74. package/dist/service-probe.js.map +1 -1
  75. package/dist/shipped-heartbeat.d.ts +1 -1
  76. package/dist/shipped-heartbeat.js +1 -1
  77. package/dist/taskPrecheck.js +6 -6
  78. package/dist/taskPrecheck.js.map +1 -1
  79. package/dist/tasks.d.ts +1 -1
  80. package/dist/tasks.d.ts.map +1 -1
  81. package/dist/tasks.js +8 -5
  82. package/dist/tasks.js.map +1 -1
  83. package/dist/todoHoardingGuard.d.ts +35 -0
  84. package/dist/todoHoardingGuard.d.ts.map +1 -0
  85. package/dist/todoHoardingGuard.js +150 -0
  86. package/dist/todoHoardingGuard.js.map +1 -0
  87. package/dist/types.d.ts +2 -2
  88. package/dist/types.d.ts.map +1 -1
  89. package/dist/working-contract.d.ts.map +1 -1
  90. package/dist/working-contract.js +59 -3
  91. package/dist/working-contract.js.map +1 -1
  92. package/package.json +1 -1
  93. package/public/dashboard.js +75 -19
  94. package/public/docs.md +17 -2
  95. package/public/polls-mock.html +1 -1
@@ -0,0 +1,150 @@
1
+ // SPDX-License-Identifier: Apache-2.0
2
+ // Copyright (c) Reflectt AI
3
+ /**
4
+ * Todo Hoarding Guard
5
+ *
6
+ * Prevents idle agents from holding too many todo tasks:
7
+ * Rule A — Cap: if assignee.todo > TODO_CAP && assignee.doing == 0 &&
8
+ * last_activity > IDLE_THRESHOLD_MS, auto-unassign lowest-priority
9
+ * todos beyond top TODO_CAP.
10
+ * Rule B — Orphan: mark todos held by idle/offline agents as orphaned
11
+ * so they don't count toward ready-floor supply.
12
+ * Rule C — Claim: /tasks/next?claim=1 auto-transitions todo→doing.
13
+ */
14
+ import { taskManager } from './tasks.js';
15
+ // ── Config ─────────────────────────────────────────────────────────────────
16
+ /** Max todo tasks per agent before auto-unassign kicks in */
17
+ export const TODO_CAP = 3;
18
+ /** Agent must be idle for this long (no doing tasks + no activity) before unassign */
19
+ export const IDLE_THRESHOLD_MS = 30 * 60 * 1000; // 30 minutes
20
+ /** Priority ordering (lower index = higher priority, kept first) */
21
+ const PRIORITY_ORDER = ['P0', 'P1', 'P2', 'P3'];
22
+ // ── Helpers ────────────────────────────────────────────────────────────────
23
+ function priorityRank(p) {
24
+ const idx = PRIORITY_ORDER.indexOf(p);
25
+ return idx >= 0 ? idx : PRIORITY_ORDER.length;
26
+ }
27
+ /**
28
+ * Get the most recent activity timestamp for an agent.
29
+ * Activity = last task update.
30
+ */
31
+ function getAgentLastActivity(agent, allTasks) {
32
+ let latest = 0;
33
+ for (const t of allTasks) {
34
+ if (t.assignee?.toLowerCase() !== agent.toLowerCase())
35
+ continue;
36
+ const ts = typeof t.updatedAt === 'number' ? t.updatedAt : 0;
37
+ if (ts > latest)
38
+ latest = ts;
39
+ }
40
+ return latest;
41
+ }
42
+ // ── Core Logic ─────────────────────────────────────────────────────────────
43
+ /**
44
+ * Run the hoarding sweep. Returns actions taken (or would be taken in dry-run).
45
+ */
46
+ export async function sweepTodoHoarding(opts = {}) {
47
+ const { dryRun = false } = opts;
48
+ const now = Date.now();
49
+ const allTasks = taskManager.listTasks();
50
+ // Group by assignee
51
+ const byAssignee = new Map();
52
+ for (const t of allTasks) {
53
+ if (!t.assignee || t.assignee === 'unassigned')
54
+ continue;
55
+ const agent = t.assignee.toLowerCase();
56
+ if (!byAssignee.has(agent))
57
+ byAssignee.set(agent, { todo: [], doing: [] });
58
+ const bucket = byAssignee.get(agent);
59
+ if (t.status === 'todo')
60
+ bucket.todo.push(t);
61
+ else if (t.status === 'doing')
62
+ bucket.doing.push(t);
63
+ }
64
+ const unassigned = [];
65
+ const orphaned = [];
66
+ for (const [agent, { todo, doing }] of byAssignee) {
67
+ const lastActivity = getAgentLastActivity(agent, allTasks);
68
+ const idleMs = now - lastActivity;
69
+ // Rule B: orphan detection — flag todos held by agents with 0 doing AND idle
70
+ if (doing.length === 0 && todo.length > 0 && idleMs >= IDLE_THRESHOLD_MS) {
71
+ for (const t of todo) {
72
+ orphaned.push({
73
+ taskId: t.id,
74
+ taskTitle: t.title || '',
75
+ assignee: agent,
76
+ idleMinutes: Math.round(idleMs / 60000),
77
+ });
78
+ }
79
+ }
80
+ // Rule A: auto-unassign overflow
81
+ // Skip agents actively doing work
82
+ if (doing.length > 0)
83
+ continue;
84
+ // Skip agents with todo at or below cap
85
+ if (todo.length <= TODO_CAP)
86
+ continue;
87
+ // Only unassign if idle beyond threshold
88
+ if (idleMs < IDLE_THRESHOLD_MS)
89
+ continue;
90
+ // Sort by priority (keep highest priority), then by createdAt (keep newest)
91
+ const sorted = [...todo].sort((a, b) => {
92
+ const pDiff = priorityRank(a.priority || 'P3') - priorityRank(b.priority || 'P3');
93
+ if (pDiff !== 0)
94
+ return pDiff;
95
+ // Same priority: keep more recently created
96
+ return (b.createdAt || 0) - (a.createdAt || 0);
97
+ });
98
+ // Keep top TODO_CAP, unassign the rest
99
+ const toUnassign = sorted.slice(TODO_CAP);
100
+ for (const task of toUnassign) {
101
+ // Skip pinned tasks
102
+ if (task.metadata?.pinned)
103
+ continue;
104
+ const reason = `Auto-unassigned: ${agent} held ${todo.length} todos with 0 doing and ${Math.round(idleMs / 60000)}m idle (cap: ${TODO_CAP})`;
105
+ if (!dryRun) {
106
+ await taskManager.updateTask(task.id, {
107
+ assignee: 'unassigned',
108
+ });
109
+ // Add comment for audit trail
110
+ await taskManager.addTaskComment(task.id, 'system', `🔄 ${reason}`);
111
+ }
112
+ unassigned.push({
113
+ taskId: task.id,
114
+ taskTitle: task.title || '',
115
+ previousAssignee: agent,
116
+ reason,
117
+ });
118
+ }
119
+ }
120
+ return {
121
+ unassigned,
122
+ orphaned,
123
+ scanned: allTasks.length,
124
+ timestamp: new Date().toISOString(),
125
+ };
126
+ }
127
+ /**
128
+ * Claim a task: transition from todo → doing when fetched via /tasks/next.
129
+ * Returns the updated task or null if transition fails.
130
+ */
131
+ export async function claimTask(taskId, agent) {
132
+ const task = taskManager.getTask(taskId);
133
+ if (!task)
134
+ return null;
135
+ if (task.status !== 'todo')
136
+ return null;
137
+ const updated = await taskManager.updateTask(taskId, {
138
+ status: 'doing',
139
+ assignee: agent,
140
+ metadata: {
141
+ ...(task.metadata || {}),
142
+ eta: '~60m (auto-claimed)',
143
+ },
144
+ });
145
+ if (updated) {
146
+ await taskManager.addTaskComment(taskId, 'system', `📋 Auto-claimed by ${agent} via /tasks/next?claim=1`);
147
+ }
148
+ return updated || null;
149
+ }
150
+ //# sourceMappingURL=todoHoardingGuard.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"todoHoardingGuard.js","sourceRoot":"","sources":["../src/todoHoardingGuard.ts"],"names":[],"mappings":"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"}
package/dist/types.d.ts CHANGED
@@ -25,7 +25,7 @@ export interface Task {
25
25
  id: string;
26
26
  title: string;
27
27
  description?: string;
28
- status: 'todo' | 'doing' | 'blocked' | 'validating' | 'done';
28
+ status: 'todo' | 'doing' | 'blocked' | 'validating' | 'done' | 'resolved_externally' | 'cancelled';
29
29
  assignee?: string;
30
30
  reviewer?: string;
31
31
  done_criteria?: string[];
@@ -88,7 +88,7 @@ export interface RecurringTask {
88
88
  metadata?: Record<string, unknown>;
89
89
  schedule: RecurringTaskSchedule;
90
90
  enabled: boolean;
91
- status?: 'todo' | 'doing' | 'blocked' | 'validating' | 'done';
91
+ status?: 'todo' | 'doing' | 'blocked' | 'validating' | 'done' | 'resolved_externally' | 'cancelled';
92
92
  lastRunAt?: number;
93
93
  lastSkipAt?: number;
94
94
  lastSkipReason?: string;
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAGA;;GAEG;AAEH,MAAM,WAAW,cAAc;IAC7B,EAAE,EAAE,MAAM,CAAA;IACV,IAAI,EAAE,MAAM,CAAA;IACZ,IAAI,EAAE,MAAM,CAAA;IACZ,QAAQ,EAAE,MAAM,CAAA;IAChB,GAAG,EAAE,MAAM,CAAA;CACZ;AAED,MAAM,WAAW,YAAY;IAC3B,EAAE,EAAE,MAAM,CAAA;IACV,IAAI,EAAE,MAAM,CAAA;IACZ,EAAE,CAAC,EAAE,MAAM,CAAA;IACX,OAAO,EAAE,MAAM,CAAA;IACf,SAAS,EAAE,MAAM,CAAA;IACjB,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAAA;IACpC,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;IAClC,WAAW,CAAC,EAAE,cAAc,EAAE,CAAA;CAC/B;AAED,MAAM,WAAW,IAAI;IACnB,EAAE,EAAE,MAAM,CAAA;IACV,KAAK,EAAE,MAAM,CAAA;IACb,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,MAAM,EAAE,MAAM,GAAG,OAAO,GAAG,SAAS,GAAG,YAAY,GAAG,MAAM,GAAG,qBAAqB,GAAG,WAAW,CAAA;IAClG,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,aAAa,CAAC,EAAE,MAAM,EAAE,CAAA;IACxB,SAAS,EAAE,MAAM,CAAA;IACjB,SAAS,EAAE,MAAM,CAAA;IACjB,SAAS,EAAE,MAAM,CAAA;IACjB,QAAQ,CAAC,EAAE,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,CAAA;IACpC,UAAU,CAAC,EAAE,MAAM,EAAE,CAAA;IACrB,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,IAAI,CAAC,EAAE,MAAM,EAAE,CAAA;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;IAClC,MAAM,CAAC,EAAE,MAAM,CAAA;CAChB;AAED,MAAM,MAAM,oBAAoB,GAAG,SAAS,GAAG,UAAU,GAAG,gBAAgB,GAAG,WAAW,GAAG,iBAAiB,CAAA;AAE9G,MAAM,WAAW,WAAW;IAC1B,EAAE,EAAE,MAAM,CAAA;IACV,MAAM,EAAE,MAAM,CAAA;IACd,MAAM,EAAE,MAAM,CAAA;IACd,OAAO,EAAE,MAAM,CAAA;IACf,SAAS,EAAE,MAAM,CAAA;IAEjB,uEAAuE;IACvE,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IAExB,6EAA6E;IAC7E,UAAU,CAAC,EAAE,OAAO,CAAA;IAEpB,+FAA+F;IAC/F,gBAAgB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IAEhC,mDAAmD;IACnD,cAAc,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;CAC/B;AAED,MAAM,WAAW,gBAAgB;IAC/B,EAAE,EAAE,MAAM,CAAA;IACV,MAAM,EAAE,MAAM,CAAA;IACd,IAAI,EAAE,oBAAoB,CAAA;IAC1B,KAAK,EAAE,MAAM,CAAA;IACb,SAAS,EAAE,MAAM,CAAA;IACjB,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;CAC/B;AAED,MAAM,MAAM,qBAAqB,GAC7B;IACE,IAAI,EAAE,QAAQ,CAAA;IACd,SAAS,EAAE,MAAM,CAAA;IACjB,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,MAAM,CAAC,EAAE,MAAM,CAAA;CAChB,GACD;IACE,IAAI,EAAE,UAAU,CAAA;IAChB,OAAO,EAAE,MAAM,CAAA;IACf,QAAQ,CAAC,EAAE,MAAM,CAAA;CAClB,CAAA;AAEL,MAAM,WAAW,aAAa;IAC5B,EAAE,EAAE,MAAM,CAAA;IACV,KAAK,EAAE,MAAM,CAAA;IACb,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,aAAa,CAAC,EAAE,MAAM,EAAE,CAAA;IACxB,SAAS,EAAE,MAAM,CAAA;IACjB,QAAQ,CAAC,EAAE,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,CAAA;IACpC,UAAU,CAAC,EAAE,MAAM,EAAE,CAAA;IACrB,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,IAAI,CAAC,EAAE,MAAM,EAAE,CAAA;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;IAClC,QAAQ,EAAE,qBAAqB,CAAA;IAC/B,OAAO,EAAE,OAAO,CAAA;IAChB,MAAM,CAAC,EAAE,MAAM,GAAG,OAAO,GAAG,SAAS,GAAG,YAAY,GAAG,MAAM,GAAG,qBAAqB,GAAG,WAAW,CAAA;IACnG,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,cAAc,CAAC,EAAE,MAAM,CAAA;IACvB,SAAS,EAAE,MAAM,CAAA;IACjB,SAAS,EAAE,MAAM,CAAA;IACjB,SAAS,EAAE,MAAM,CAAA;CAClB;AAED,MAAM,WAAW,cAAc;IAC7B,UAAU,EAAE,MAAM,CAAA;IAClB,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,OAAO,EAAE,MAAM,CAAA;CAChB;AAED,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAA;IACZ,IAAI,EAAE,MAAM,CAAA;IACZ,WAAW,EAAE,OAAO,CAAA;CACrB;AAED,MAAM,WAAW,QAAQ;IACvB,EAAE,EAAE,MAAM,CAAA;IACV,IAAI,EAAE,MAAM,CAAA;IACZ,YAAY,EAAE,MAAM,EAAE,CAAA;IACtB,SAAS,EAAE,MAAM,CAAA;CAClB;AAED,MAAM,WAAW,YAAa,SAAQ,YAAY;IAChD,QAAQ,EAAE,MAAM,GAAG,QAAQ,GAAG,KAAK,CAAA;IACnC,MAAM,EAAE,SAAS,GAAG,IAAI,GAAG,YAAY,GAAG,SAAS,CAAA;CACpD;AAED,MAAM,WAAW,UAAU;IACzB,KAAK,EAAE,MAAM,CAAA;IACb,aAAa,EAAE,MAAM,EAAE,CAAA;IACvB,eAAe,EAAE,MAAM,EAAE,CAAA;IACzB,iBAAiB,CAAC,EAAE,MAAM,CAAA;IAC1B,WAAW,EAAE,MAAM,CAAA;CACpB"}
@@ -1 +1 @@
1
- {"version":3,"file":"working-contract.d.ts","sourceRoot":"","sources":["../src/working-contract.ts"],"names":[],"mappings":"AAmBA,MAAM,WAAW,qBAAqB;IACpC,OAAO,EAAE,OAAO,CAAA;IAChB,mBAAmB,EAAE,MAAM,CAAA;IAC3B,oBAAoB,EAAE,MAAM,CAAA;IAC5B,qBAAqB,EAAE,OAAO,CAAA;IAC9B,MAAM,EAAE,MAAM,EAAE,CAAA;IAChB,OAAO,EAAE,MAAM,CAAA;IACf,MAAM,EAAE,OAAO,CAAA;CAChB;AAED,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,SAAS,GAAG,cAAc,GAAG,uBAAuB,CAAA;IAC1D,KAAK,EAAE,MAAM,CAAA;IACb,MAAM,EAAE,MAAM,CAAA;IACd,SAAS,EAAE,MAAM,CAAA;IACjB,MAAM,EAAE,MAAM,CAAA;IACd,SAAS,EAAE,MAAM,CAAA;IACjB,MAAM,EAAE,OAAO,CAAA;CAChB;AAED,MAAM,WAAW,UAAU;IACzB,QAAQ,EAAE,MAAM,CAAA;IAChB,QAAQ,EAAE,MAAM,CAAA;IAChB,OAAO,EAAE,iBAAiB,EAAE,CAAA;CAC7B;AAED,MAAM,WAAW,eAAe;IAC9B,OAAO,EAAE,OAAO,CAAA;IAChB,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,IAAI,CAAC,EAAE,oBAAoB,CAAA;IAC3B,cAAc,CAAC,EAAE,MAAM,CAAA;CACxB;AAQD;;;GAGG;AACH,wBAAsB,mBAAmB,IAAI,OAAO,CAAC,UAAU,CAAC,CA+G/D;AAID;;;GAGG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,MAAM,GAAG,eAAe,CAkE7D;AAqCD,wBAAgB,cAAc,IAAI,IAAI,CAErC;AAED,wBAAgB,YAAY,IAAI,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAElD"}
1
+ {"version":3,"file":"working-contract.d.ts","sourceRoot":"","sources":["../src/working-contract.ts"],"names":[],"mappings":"AAmBA,MAAM,WAAW,qBAAqB;IACpC,OAAO,EAAE,OAAO,CAAA;IAChB,mBAAmB,EAAE,MAAM,CAAA;IAC3B,oBAAoB,EAAE,MAAM,CAAA;IAC5B,qBAAqB,EAAE,OAAO,CAAA;IAC9B,MAAM,EAAE,MAAM,EAAE,CAAA;IAChB,OAAO,EAAE,MAAM,CAAA;IACf,MAAM,EAAE,OAAO,CAAA;CAChB;AAED,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,SAAS,GAAG,cAAc,GAAG,uBAAuB,CAAA;IAC1D,KAAK,EAAE,MAAM,CAAA;IACb,MAAM,EAAE,MAAM,CAAA;IACd,SAAS,EAAE,MAAM,CAAA;IACjB,MAAM,EAAE,MAAM,CAAA;IACd,SAAS,EAAE,MAAM,CAAA;IACjB,MAAM,EAAE,OAAO,CAAA;CAChB;AAED,MAAM,WAAW,UAAU;IACzB,QAAQ,EAAE,MAAM,CAAA;IAChB,QAAQ,EAAE,MAAM,CAAA;IAChB,OAAO,EAAE,iBAAiB,EAAE,CAAA;CAC7B;AAED,MAAM,WAAW,eAAe;IAC9B,OAAO,EAAE,OAAO,CAAA;IAChB,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,IAAI,CAAC,EAAE,oBAAoB,CAAA;IAC3B,cAAc,CAAC,EAAE,MAAM,CAAA;CACxB;AA6DD;;;GAGG;AACH,wBAAsB,mBAAmB,IAAI,OAAO,CAAC,UAAU,CAAC,CAmH/D;AAID;;;GAGG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,MAAM,GAAG,eAAe,CAkE7D;AAqCD,wBAAgB,cAAc,IAAI,IAAI,CAErC;AAED,wBAAgB,YAAY,IAAI,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAElD"}
@@ -14,7 +14,60 @@ import { routeMessage } from './messageRouter.js';
14
14
  import { listReflections } from './reflections.js';
15
15
  import { getEffectiveActivity, formatActivityWarning } from './activity-signal.js';
16
16
  // ── State: track warnings ──
17
- const warningTimestamps = new Map(); // key: `${agent}:${taskId}`
17
+ /**
18
+ * warningTimestamps: key → epoch ms when Phase 1 warning was issued.
19
+ *
20
+ * Backed by SQLite so restarts don't re-fire warnings. In-memory cache
21
+ * is seeded from DB on first use.
22
+ *
23
+ * Root cause of compliance snapshot 3x bug: this was previously a plain
24
+ * in-memory Map that reset on every server restart. Each restart would
25
+ * re-fire the Phase 1 warning for every stale doing task. The stale
26
+ * duration increments between restarts (e.g. "stale for 45m" vs "46m"),
27
+ * which bypassed chat.ts content dedup, resulting in 2–3x identical-
28
+ * looking warning messages per agent per deploy cycle.
29
+ */
30
+ const warningTimestamps = new Map();
31
+ let _warningDbSeeded = false;
32
+ function ensureWarningTable() {
33
+ const db = getDb();
34
+ db.prepare(`
35
+ CREATE TABLE IF NOT EXISTS wc_warning_timestamps (
36
+ key TEXT PRIMARY KEY,
37
+ warned_at INTEGER NOT NULL
38
+ )
39
+ `).run();
40
+ }
41
+ function seedWarningTimestamps() {
42
+ if (_warningDbSeeded)
43
+ return;
44
+ _warningDbSeeded = true;
45
+ try {
46
+ ensureWarningTable();
47
+ const db = getDb();
48
+ const rows = db.prepare('SELECT key, warned_at FROM wc_warning_timestamps').all();
49
+ for (const row of rows) {
50
+ warningTimestamps.set(row.key, row.warned_at);
51
+ }
52
+ }
53
+ catch { /* db may not be ready */ }
54
+ }
55
+ function persistWarning(key, timestamp) {
56
+ try {
57
+ ensureWarningTable();
58
+ const db = getDb();
59
+ db.prepare('INSERT OR REPLACE INTO wc_warning_timestamps (key, warned_at) VALUES (?, ?)').run(key, timestamp);
60
+ }
61
+ catch { /* best-effort */ }
62
+ }
63
+ function clearWarning(key) {
64
+ warningTimestamps.delete(key);
65
+ try {
66
+ const db = getDb();
67
+ db.prepare('DELETE FROM wc_warning_timestamps WHERE key = ?').run(key);
68
+ }
69
+ catch { /* best-effort */ }
70
+ }
18
71
  // ── Enforcement tick ──
19
72
  /**
20
73
  * Called periodically. Checks all 'doing' tasks for stale status.
@@ -24,6 +77,8 @@ export async function tickWorkingContract() {
24
77
  const config = getConfig();
25
78
  if (!config.enabled)
26
79
  return { warnings: 0, requeued: 0, actions: [] };
80
+ // Seed warningTimestamps from DB on first tick (survives process restarts)
81
+ seedWarningTimestamps();
27
82
  const now = Date.now();
28
83
  const staleThresholdMs = config.staleAutoRequeueMin * 60_000;
29
84
  const graceMs = config.graceAfterWarningMin * 60_000;
@@ -51,6 +106,7 @@ export async function tickWorkingContract() {
51
106
  if (!warnedAt) {
52
107
  // Phase 1: Issue warning
53
108
  warningTimestamps.set(warningKey, now);
109
+ persistWarning(warningKey, now);
54
110
  const signalInfo = formatActivityWarning(activitySignal, config.staleAutoRequeueMin, now);
55
111
  const action = {
56
112
  type: 'warning',
@@ -80,7 +136,7 @@ export async function tickWorkingContract() {
80
136
  const activitySinceWarning = getLastActivityForAgent(task.id, agent);
81
137
  if (activitySinceWarning && activitySinceWarning > warnedAt) {
82
138
  // Agent responded — clear warning
83
- warningTimestamps.delete(warningKey);
139
+ clearWarning(warningKey);
84
140
  continue;
85
141
  }
86
142
  // Auto-requeue
@@ -95,7 +151,7 @@ export async function tickWorkingContract() {
95
151
  };
96
152
  actions.push(action);
97
153
  requeued++;
98
- warningTimestamps.delete(warningKey);
154
+ clearWarning(warningKey);
99
155
  if (!config.dryRun) {
100
156
  try {
101
157
  // Move task back to todo, clear assignee
@@ -1 +1 @@
1
- {"version":3,"file":"working-contract.js","sourceRoot":"","sources":["../src/working-contract.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"working-contract.js","sourceRoot":"","sources":["../src/working-contract.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "reflectt-node",
3
- "version": "0.1.4",
3
+ "version": "0.1.5",
4
4
  "description": "Coordinate your AI agent team. Shared tasks, memory, reflections, and presence. Self-host for free.",
5
5
  "main": "dist/index.js",
6
6
  "type": "module",
@@ -71,8 +71,14 @@ function updateFirstBootBanner() {
71
71
  const el = document.getElementById('first-boot-banner');
72
72
  if (!el) return;
73
73
  const dismissed = localStorage.getItem('reflectt-first-boot-dismissed');
74
- const hasTasks = allTasks.length > 0;
75
- el.hidden = dismissed === '1' || hasTasks;
74
+ // We seed a welcome task on first boot, so `allTasks.length > 0` is not a good proxy for
75
+ // "user has started using the system". Only hide the banner once a *non-seeded* task exists.
76
+ const seededSources = new Set(['first-boot', 'first-boot-intent']);
77
+ const hasRealTasks = allTasks.some(t => {
78
+ const src = t && t.metadata && t.metadata.source;
79
+ return !src || !seededSources.has(src);
80
+ });
81
+ el.hidden = dismissed === '1' || hasRealTasks;
76
82
  }
77
83
  function dismissFirstBootBanner() {
78
84
  localStorage.setItem('reflectt-first-boot-dismissed', '1');
@@ -80,6 +86,14 @@ function dismissFirstBootBanner() {
80
86
  if (el) el.hidden = true;
81
87
  }
82
88
 
89
+ function updateOverviewEmptyState() {
90
+ const el = document.getElementById('overview-empty-state');
91
+ if (!el) return;
92
+ const hasTasks = allTasks.length > 0;
93
+ const hasMessages = allMessages.length > 0;
94
+ el.style.display = (hasTasks || hasMessages) ? 'none' : '';
95
+ }
96
+
83
97
  // Delta cursors for lower payload refreshes
84
98
  let lastTaskSync = 0;
85
99
  let lastChatSync = 0;
@@ -258,7 +272,7 @@ function renderLaneTransitionMeta(task) {
258
272
  return `<div style="margin-top:6px;font-size:11px;color:var(--text-muted)">🧭 ${esc(parts.join(' · '))}</div>`;
259
273
  }
260
274
 
261
- function mentionsRyan(message) { return /@ryan\b/i.test(message || ''); }
275
+ function hasMention(message) { return /@([a-zA-Z][a-zA-Z0-9_-]*)/i.test(message || ''); }
262
276
 
263
277
  function resolveSSOTState(lastVerifiedUtc) {
264
278
  if (!lastVerifiedUtc) return { state: 'unknown', label: 'unknown', text: 'verification timestamp unavailable' };
@@ -450,12 +464,12 @@ function formatDurationMin(min) {
450
464
 
451
465
  function statusTemplateFor(agent, taskId) {
452
466
  const mentions = agent === 'pixel'
453
- ? '@kai @link'
467
+ ? '@owner @link'
454
468
  : agent === 'link'
455
- ? '@kai @pixel'
469
+ ? '@owner @pixel'
456
470
  : agent === 'kai'
457
471
  ? '@link @pixel'
458
- : '@kai @pixel';
472
+ : '@owner @pixel';
459
473
  return [
460
474
  mentions,
461
475
  'Task: ' + (taskId || '<task-id>'),
@@ -717,6 +731,7 @@ async function loadTasks(forceFull = false) {
717
731
  const navTaskBadge = document.getElementById('nav-task-count');
718
732
  if (navTaskBadge) navTaskBadge.textContent = allTasks.length;
719
733
  updateFirstBootBanner();
734
+ updateOverviewEmptyState();
720
735
  }
721
736
 
722
737
  function renderProjectTabs() {
@@ -741,7 +756,7 @@ function toggleTestTasks() {
741
756
  renderStatusFilterTabs();
742
757
  renderKanban();
743
758
  // Update task count
744
- const openCount = getVisibleTasks().filter(t => t.status !== 'done').length;
759
+ const openCount = getVisibleTasks().filter(t => !['done', 'resolved_externally', 'cancelled'].includes(t.status)).length;
745
760
  document.getElementById('task-count').textContent = currentStatusFilter === 'open'
746
761
  ? openCount + ' open tasks'
747
762
  : getVisibleTasks().length + ' tasks';
@@ -779,20 +794,45 @@ function renderKanban() {
779
794
  const filtered = currentProject === 'all' ? visible : visible.filter(t => classifyProject(t) === currentProject);
780
795
  const cols = currentStatusFilter === 'open'
781
796
  ? ['todo', 'doing', 'blocked', 'validating']
782
- : ['todo', 'doing', 'blocked', 'validating', 'done'];
797
+ : ['todo', 'doing', 'blocked', 'validating', 'done', 'resolved_externally', 'cancelled'];
783
798
  const grouped = {}; cols.forEach(c => grouped[c] = []);
784
- filtered.forEach(t => { const s = t.status || 'todo'; if (grouped[s]) grouped[s].push(t); else grouped['todo'].push(t); });
799
+ const tasksForBoard = currentStatusFilter === 'open'
800
+ ? filtered.filter(t => cols.includes(t.status || 'todo'))
801
+ : filtered;
802
+ tasksForBoard.forEach(t => { const s = t.status || 'todo'; if (grouped[s]) grouped[s].push(t); else grouped['todo'].push(t); });
785
803
  const pOrder = { P0: 0, P1: 1, P2: 2, P3: 3 };
786
804
  cols.forEach(c => grouped[c].sort((a, b) => (pOrder[a.priority] ?? 9) - (pOrder[b.priority] ?? 9)));
787
805
 
788
806
  const kanban = document.getElementById('kanban');
807
+
808
+ // Full-board empty state: no tasks at all
809
+ const totalOnBoard = tasksForBoard.length;
810
+ if (totalOnBoard === 0) {
811
+ kanban.innerHTML = '<div class="board-empty-state" style="grid-column:1/-1;text-align:center;padding:40px 20px;color:var(--text-muted)">'
812
+ + '<div style="font-size:28px;margin-bottom:12px">📋</div>'
813
+ + '<div style="font-size:15px;font-weight:500;color:var(--text-bright);margin-bottom:6px">No tasks yet</div>'
814
+ + '<div style="font-size:13px;max-width:340px;margin:0 auto;line-height:1.5">Create your first task via the API, or connect an AI agent to start generating work automatically.</div>'
815
+ + '<div style="margin-top:14px;display:flex;gap:10px;justify-content:center;flex-wrap:wrap">'
816
+ + '<a href="/docs" target="_blank" style="color:var(--accent);font-size:12px;text-decoration:none">API reference →</a>'
817
+ + '<a href="/capabilities" target="_blank" style="color:var(--accent);font-size:12px;text-decoration:none">Capabilities →</a>'
818
+ + '</div></div>';
819
+ return;
820
+ }
821
+
789
822
  kanban.innerHTML = cols.map(col => {
790
823
  const items = grouped[col];
791
824
  const isDone = col === 'done';
792
825
  const isTodo = col === 'todo';
793
826
  const colLimit = isDone ? 3 : isTodo ? 10 : items.length;
827
+ const emptyMessages = {
828
+ todo: 'No tasks queued',
829
+ doing: 'Nothing in progress',
830
+ blocked: 'Nothing blocked',
831
+ validating: 'Nothing awaiting review',
832
+ done: 'No completed tasks yet',
833
+ };
794
834
  const cards = items.length === 0
795
- ? '<div class="empty">—</div>'
835
+ ? '<div class="empty" style="font-size:12px;padding:12px 8px">' + (emptyMessages[col] || '—') + '</div>'
796
836
  : items.map((t, idx) => {
797
837
  const isHidden = idx >= colLimit;
798
838
  const assigneeAgent = t.assignee ? AGENTS.find(a => a.name === t.assignee) : null;
@@ -1032,13 +1072,13 @@ async function loadChat(forceFull = false) {
1032
1072
  if (!channelStats.has(ch)) channelStats.set(ch, { total: 0, mentions: 0 });
1033
1073
  const stats = channelStats.get(ch);
1034
1074
  stats.total += 1;
1035
- if (mentionsRyan(m.content)) stats.mentions += 1;
1075
+ if (hasMention(m.content)) stats.mentions += 1;
1036
1076
  });
1037
1077
 
1038
1078
  const tabs = document.getElementById('channel-tabs');
1039
1079
  tabs.innerHTML = Array.from(channels).map(ch => {
1040
1080
  const stats = ch === 'all'
1041
- ? { total: allMessages.length, mentions: allMessages.filter(m => mentionsRyan(m.content)).length }
1081
+ ? { total: allMessages.length, mentions: allMessages.filter(m => hasMention(m.content)).length }
1042
1082
  : (channelStats.get(ch) || { total: 0, mentions: 0 });
1043
1083
  const label = ch === 'all' ? '🌐 all' : '#' + esc(ch);
1044
1084
  const countMeta = `<span class="meta">${stats.total}</span>`;
@@ -1069,7 +1109,7 @@ function renderChat() {
1069
1109
  body.innerHTML = shown.map(m => {
1070
1110
  const agent = AGENT_INDEX.get(m.from);
1071
1111
  const roleTag = agent ? `<span class="msg-role">${esc(agent.role)}</span>` : '';
1072
- const mentioned = mentionsRyan(m.content);
1112
+ const mentioned = hasMention(m.content);
1073
1113
  const channelTag = m.channel ? '<span class="msg-channel">#' + esc(m.channel) + '</span>' : '';
1074
1114
  const editedTag = m.metadata && m.metadata.editedAt ? '<span class="msg-edited">(edited)</span>' : '';
1075
1115
  return `
@@ -1294,9 +1334,9 @@ async function loadSharedArtifacts() {
1294
1334
  const files = entries.filter(e => e && e.type === 'file');
1295
1335
  count.textContent = files.length + ' files';
1296
1336
 
1297
- // Pinned: Ryan's thoughts (if symlinked into shared workspace process/)
1337
+ // Pinned: operator notes (optional)
1298
1338
  const pinned = [
1299
- { name: "RYANS-THOUGHTS.md", label: "Ryan's thoughts" },
1339
+ { name: "OPERATOR-NOTES.md", label: "Operator notes" },
1300
1340
  ];
1301
1341
 
1302
1342
  const pinnedRows = pinned.map(p => {
@@ -1555,6 +1595,7 @@ async function loadReleaseStatus(force = false) {
1555
1595
  badge.classList.toggle('stale', stale);
1556
1596
  badge.classList.toggle('fresh', !stale);
1557
1597
  badge.textContent = stale ? 'deploy: stale' : 'deploy: in sync';
1598
+ badge.style.display = '';
1558
1599
 
1559
1600
  const reasons = Array.isArray(status.reasons) ? status.reasons : [];
1560
1601
  const startupCommit = status.startup && status.startup.commit ? status.startup.commit.slice(0, 8) : 'unknown';
@@ -1590,6 +1631,7 @@ async function loadBuildInfo() {
1590
1631
  badge.classList.toggle('stale', branch !== 'main');
1591
1632
  badge.textContent = `${sha} • ${uptimeStr}`;
1592
1633
  badge.title = `SHA: ${info.gitSha}\nBranch: ${branch}\nCommit: ${info.gitMessage}\nAuthor: ${info.gitAuthor}\nPID: ${info.pid}\nNode: ${info.nodeVersion}\nStarted: ${info.startedAt}`;
1634
+ badge.style.display = '';
1593
1635
  } catch (err) {
1594
1636
  badge.textContent = 'build: error';
1595
1637
  badge.title = 'Failed to load build info';
@@ -1708,7 +1750,16 @@ function renderReviewQueue() {
1708
1750
  });
1709
1751
 
1710
1752
  if (validating.length === 0) {
1711
- panel.style.display = 'none';
1753
+ panel.style.display = '';
1754
+ count.textContent = '';
1755
+ body.innerHTML = '<div style="text-align:center;padding:24px 16px;color:var(--text-muted)">'
1756
+ + '<div style="font-size:22px;margin-bottom:8px">✓</div>'
1757
+ + '<div style="font-size:13px;font-weight:500;color:var(--text-bright);margin-bottom:4px">Review queue is clear</div>'
1758
+ + '<div style="font-size:12px;line-height:1.5">Tasks move here when they enter <em>validating</em>. Reviewers will see SLA timers and can approve or request changes.</div>'
1759
+ + '</div>';
1760
+ // Clear sidebar badge
1761
+ const navReviewBadge = document.getElementById('nav-review-count');
1762
+ if (navReviewBadge) navReviewBadge.textContent = '0';
1712
1763
  return;
1713
1764
  }
1714
1765
 
@@ -1770,7 +1821,7 @@ async function escalateReviewBreaches(breachedTasks) {
1770
1821
  return '- ' + t.id + ' (' + (t.title || '').slice(0, 50) + ') — reviewer: @' + reviewer + ', waiting ' + formatDuration(t.timeInReview);
1771
1822
  });
1772
1823
 
1773
- const content = '@kai Review SLA breach detected:\n' + lines.join('\n');
1824
+ const content = '@owner Review SLA breach detected:\n' + lines.join('\n');
1774
1825
 
1775
1826
  try {
1776
1827
  await fetch(BASE + '/chat/messages', {
@@ -2749,6 +2800,11 @@ function toggleFocusMode() {
2749
2800
  // Persist preference
2750
2801
  try { localStorage.setItem('reflectt-focus-mode', focusModeActive ? '1' : '0'); } catch {}
2751
2802
 
2803
+ // Show/hide dev-only panels
2804
+ document.querySelectorAll('.panel.focus-only').forEach(panel => {
2805
+ panel.style.display = focusModeActive ? '' : 'none';
2806
+ });
2807
+
2752
2808
  // Re-render kanban to add/remove QA contract details
2753
2809
  renderKanban();
2754
2810
 
@@ -2840,9 +2896,9 @@ async function checkGettingStarted() {
2840
2896
  const hasTasks = (health.tasks?.total || 0) > 0;
2841
2897
  const hasMessages = (health.chat?.total || 0) > 0;
2842
2898
 
2843
- // Step 1: preflight — done if server is healthy
2899
+ // Step 1: server running always done if dashboard loads
2844
2900
  const step1 = document.getElementById('gs-preflight');
2845
- if (step1 && hasHeartbeat) {
2901
+ if (step1) {
2846
2902
  step1.classList.add('done');
2847
2903
  step1.querySelector('.gs-icon').textContent = '✓';
2848
2904
  }
package/public/docs.md CHANGED
@@ -41,6 +41,16 @@ Returns `text/html`. No parameters.
41
41
  open http://localhost:4445/ui-kit
42
42
  ```
43
43
 
44
+ ### `GET /dashboard`
45
+
46
+ Main `reflectt-node` dashboard UI.
47
+
48
+ Returns `text/html`.
49
+
50
+ Internal/cockpit controls are hidden by default. To enable them (for operators debugging their own host), start the server with `REFLECTT_INTERNAL_UI=1` **and** open:
51
+
52
+ - `http://localhost:4445/dashboard?internal=1`
53
+
44
54
  ---
45
55
 
46
56
  ## Error Envelope (all endpoints)
@@ -102,6 +112,7 @@ Remote hosts (multi-host installs) phone-home via a lightweight heartbeat so the
102
112
  | GET | `/health/team` | Team health metrics with compliance + `staleDoing` snapshot. Per-agent rows include `activeTaskTitle` and `activeTaskPrLink` when an agent has a doing task with PR evidence. Flagged agents also include `actionable_reason` (last comment age, last transition, last mention age, suggested action). |
103
113
  | GET | `/health/agents` | Per-agent health summary (`last_seen`, `active_task`, `heartbeat_age_ms`, `last_shipped_at`, `stale_reason`, state) |
104
114
  | GET | `/health/compliance` | Compliance check results |
115
+ | GET | `/compliance/violations` | State-read-before-assertion compliance violations. Query: `agent`, `severity`, `limit` (max 1000), `since` (epoch ms). Returns `{ violations, count, summary, query }`. |
105
116
  | GET | `/health/backlog` | Backlog readiness health by lane (ready counts, floor compliance, breach status, blocked/todo/doing/validating rollups). Query: `include_test=1` to include test-harness tasks. |
106
117
  | GET | `/health/system` | System + loop/timer health (quiet-hours suppression, sweeper status, watchdog tick timestamps, uptime/memory) |
107
118
  | GET | `/health/build` | Build/runtime identity (version, git SHA, branch, build timestamp, PID, uptime) |
@@ -109,9 +120,11 @@ Remote hosts (multi-host installs) phone-home via a lightweight heartbeat so the
109
120
  | GET | `/health/team/summary` | Compact team health summary |
110
121
  | GET | `/health/team/history` | Historical team health data |
111
122
  | GET | `/health/workflow` | Unified per-agent workflow state: doing-task age, last shipped timestamp, blocker flag, artifact path, and linked PR state. Query: `include_test=1` to include test-harness tasks. |
112
- | GET | `/health/reflection-pipeline` | Reflection→Insight→Promotion health signal. Returns recent reflection/insight/promotion counts, status (`healthy`\|`at_risk`\|`broken`), and alert timestamps. Triggers alert when reflections flow but insights remain zero past threshold. |
123
+ | GET | `/health/reflection-pipeline` | Reflection→Insight→Promotion health signal. Returns recent reflection/insight/promotion counts, status (`idle`\|`healthy`\|`at_risk`\|`broken`), and alert timestamps. Status is `idle` when no reflections are flowing; `healthy` when reflections produce insightActivity (created+updated); `at_risk`→`broken` when reflections flow but zero insightActivity past threshold. |
113
124
  | GET | `/health/backlog` | Backlog readiness snapshot by lane/agent with ready-floor breach detection and stale-validating summary. Query: `include_test=1` to include test-harness tasks. |
114
125
  | GET | `/health/alert-preflight` | Alert-preflight guard metrics: total checked, canary-flagged, suppressed, false-positive rate, mode (canary/enforce/off). |
126
+ | GET | `/health/alert-preflight/history` | Daily alert-preflight snapshots for observation window tracking. Returns per-day metrics + current session. |
127
+ | GET | `/health/hoarding` | Todo hoarding guard status: orphaned todos, auto-unassign actions, config. Query: `dry_run=0` to run live (default: dry run). |
115
128
  | GET | `/health/mention-ack` | Mention-ack lifecycle metrics (pending, timeout, latency counters) |
116
129
  | GET | `/health/mention-ack/recent` | Recent mention-ack entries for debugging. Query: `limit` (max 100) |
117
130
  | GET | `/health/mention-ack/:agent` | Pending mention-ack entries for one agent |
@@ -179,7 +192,7 @@ If your deployment needs quiet-hours behavior today, enforce it in scheduler/gat
179
192
  | POST | `/tasks` | Create task. Required: `title`, `createdBy`, `assignee`, `reviewer`, `done_criteria` (string[]), `eta`. Optional: `description`, `priority` (P0-P3), `status`, `tags`, `metadata`. **Reflection-origin invariant:** `metadata.source_reflection` or `metadata.source_insight` required (or `metadata.reflection_exempt=true` with `reflection_exempt_reason`). Status contract: `validating` also requires `metadata.artifact_path` under `process/`. |
180
193
  | PATCH | `/tasks/:id` | Update task (partial). Any task field, plus optional `actor` for history attribution. Status contract: `doing` requires reviewer + `metadata.eta`; `validating` requires `metadata.artifact_path` under `process/` (workspace-agnostic). |
181
194
  | DELETE | `/tasks/:id` | Delete task |
182
- | GET | `/tasks/next` | Pull-based assignment. Query: `agent`, `compact` |
195
+ | GET | `/tasks/next` | Pull-based assignment. Query: `agent`, `compact`, `claim=1` (auto-transitions todo→doing on pull) |
183
196
  | GET | `/tasks/active` | Get active (doing) task for agent. Query: `agent`, `compact`. Returns null if no doing tasks. |
184
197
  | GET | `/heartbeat/:agent` | Single compact heartbeat payload (~200 tokens). Returns active task, next task, slim inbox, queue counts, and suggested action. Replaces 3 separate API calls. |
185
198
  | GET | `/bootstrap/heartbeat/:agent` | Generate optimal HEARTBEAT.md content for agent. References best endpoints. Includes version stamp and content hash for change detection. |
@@ -202,6 +215,7 @@ If your deployment needs quiet-hours behavior today, enforce it in scheduler/gat
202
215
  | GET | `/tasks/board-health` | Board-level health metrics for backlog replenishment. Returns per-agent breakdown (doing, validating, todo, active counts), `needsWork`/`lowWatermark` flags, and `replenishNeeded` trigger (fires when 2+ agents idle or <3 backlog tasks). Query: `include_test=1` to include test-harness tasks. |
203
216
  | GET | `/agents/roles` | Agent role registry with live WIP status. Returns all agents with `name`, `displayName`, `role`, `affinityTags`, `protectedDomains`, `wipCap`, `wipCount`, `overCap`. |
204
217
  | POST | `/config/identity` | Set an agent's display name. Body: `{ "agent": "agent-1", "displayName": "Juniper" }`. Persists to TEAM-ROLES.yaml, hot-reloads. Dashboard and mentions use display name. |
218
+ | PUT | `/config/team-roles` | Write TEAM-ROLES.yaml. Body: `{ "yaml": "agents:\n - name: link\n role: engineer..." }`. Hot-reloads on save. Used by bootstrap agent to configure team from user intent. |
205
219
  | GET | `/resolve/mention/:mention` | Resolve a mention string (name, displayName, or alias) to canonical agent ID. Returns `{ agent, displayName, role }`. |
206
220
  | POST | `/tasks/suggest-assignee` | Suggest best assignee for a task. Body: `{ "title": "...", "tags": [...], "done_criteria": [...] }`. Returns `suggested` agent name, `scores` array with affinity/WIP/throughput breakdown, and `protectedMatch` if a protected domain applies. |
207
221
  | GET | `/team/manifest` | Serve TEAM.md from `~/.reflectt/` (falls back to defaults). Returns `manifest` object with `raw_markdown`, parsed `sections` array, `version` (SHA-256 hash), `updated_at`, `path`, and `source`. |
@@ -479,6 +493,7 @@ Preflight checks reconcile live task state (status, assignee, reviewer, recent c
479
493
  | Method | Path | Description |
480
494
  |--------|------|-------------|
481
495
  | GET | `/cloud/status` | Cloud connection state (registered, heartbeat age, sync status). Only active when `REFLECTT_HOST_TOKEN` is set. |
496
+ | GET | `/cloud/events` | Connection lifecycle events (connect, disconnect, heartbeat failures/recoveries). Query: `?limit=N` (max 100). |
482
497
  | POST | `/cloud/reload` | Hot-reload cloud config from `~/.reflectt/config.json` without server restart. Updates env vars and restarts heartbeat/sync loops. Used by CLI after `host connect` enrollment. |
483
498
  | GET | `/provisioning/status` | Host provisioning state: phase, enrollment, config/secrets pull status, webhook routes. Dashboard-safe (no credentials). |
484
499
  | POST | `/provisioning/provision` | Full provisioning flow: enroll with cloud (join token or API key), pull config + secrets, configure webhooks. Body: `{ cloudUrl, hostName, joinToken?, apiKey?, capabilities? }`. |