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
package/README.md CHANGED
@@ -3,209 +3,118 @@
3
3
  [![npm version](https://img.shields.io/npm/v/reflectt-node?color=cb3837&logo=npm)](https://www.npmjs.com/package/reflectt-node)
4
4
  [![License: Apache-2.0](https://img.shields.io/badge/license-Apache--2.0-blue.svg)](LICENSE)
5
5
  [![GitHub stars](https://img.shields.io/github/stars/reflectt/reflectt-node?style=social)](https://github.com/reflectt/reflectt-node)
6
- [![Discord](https://img.shields.io/discord/reflectt?label=Discord&logo=discord&logoColor=white)](https://discord.gg/reflectt)
6
+ [![Discord](https://img.shields.io/discord/1467241374746415195?label=Discord&logo=discord&logoColor=white)](https://discord.gg/gMbWskMkbT)
7
7
 
8
- **Local coordination server for AI agent teams.** Tasks, chat, memory, reflections, file uploads, and a live dashboard — running on your hardware.
8
+ reflectt-node is a local coordination server for AI agent teams.
9
9
 
10
- Tell your AI agent to follow the bootstrap: **[reflectt.ai/bootstrap](https://reflectt.ai/bootstrap)**
10
+ It provides shared coordination primitives task state (todo → doing → validating → done), presence/heartbeats, and reviewer handoffs — so you can see what’s happening without acting as a human PM.
11
11
 
12
- > 🚀 Running in production: 3 teams (bare metal + Docker + Fly.io), 9 agents, shipping daily.
12
+ Runs locally (no cloud required). If you’re using OpenClaw, it works well with those agent workflows; otherwise connect any runner via the HTTP API.
13
13
 
14
- ---
15
-
16
- ## Quickstart (2 minutes)
17
-
18
- ```bash
19
- npm install -g reflectt-node # Install globally
20
- reflectt init # Set up ~/.reflectt/
21
- reflectt start # Start the server
22
- ```
23
-
24
- Open [http://localhost:4445/dashboard](http://localhost:4445/dashboard) — a starter team and welcome task are waiting.
25
-
26
- **Connect to cloud (optional):** `reflectt host connect --join-token <token>`
27
- Get your token at [app.reflectt.ai](https://app.reflectt.ai) → create a team → Settings → Join token.
14
+ > Running in production: 8 agents, 3 nodes, 1,362 tasks — 1,344 done.
28
15
 
29
16
  ---
30
17
 
31
- ## Get Started
32
-
33
- ### Option 1: Tell your agent
34
-
35
- Paste this into any AI chat (OpenClaw, Claude, ChatGPT, Cursor — anything with web access):
36
-
37
- ```
38
- Follow the bootstrap instructions at reflectt.ai/bootstrap
39
- ```
40
-
41
- Your agent reads the instructions, installs reflectt-node, and starts coordinating.
18
+ ## Install
42
19
 
43
- ### Option 2: npm
20
+ ### Quick try (no global install)
44
21
 
45
22
  ```bash
46
- npm install -g reflectt-node
47
- reflectt init && reflectt start
23
+ npx reflectt-node
48
24
  ```
49
25
 
50
- ### Option 3: Docker
26
+ Then open http://127.0.0.1:4445/dashboard (or the URL printed in your terminal).
51
27
 
52
- ```bash
53
- docker run -d --name reflectt-node \
54
- -p 4445:4445 \
55
- -v reflectt-data:/data \
56
- ghcr.io/reflectt/reflectt-node:latest
57
- ```
28
+ ### Install globally
58
29
 
59
- ### Option 4: From source
60
30
 
61
31
  ```bash
62
- git clone https://github.com/reflectt/reflectt-node.git
63
- cd reflectt-node
64
- npm install && npm run build && npm start
32
+ npm install -g reflectt-node
33
+ reflectt init
34
+ reflectt start
65
35
  ```
66
36
 
67
- **Then open:** [http://localhost:4445/dashboard](http://localhost:4445/dashboard)
68
-
69
- ---
37
+ Open [http://localhost:4445/dashboard](http://localhost:4445/dashboard). A starter team and first task are ready.
70
38
 
71
- ## What You Get
39
+ ## First 5 minutes (GitHub quickstart)
72
40
 
73
- | Feature | What it does |
74
- |---------|-------------|
75
- | **Task Board** | Full CRUD with priority, assignees, reviewers, state machine gates |
76
- | **Agent Chat** | Real-time messaging via REST + WebSocket, file attachments |
77
- | **Live Dashboard** | 8-page browser UI — tasks, chat, reviews, health, outcomes, research, artifacts |
78
- | **File Uploads** | Drag-drop upload, file browser (grid/list), chat attachments via 📎 |
79
- | **Team Health** | Presence tracking, blocker detection, idle nudges, compliance metrics |
80
- | **Reflections** | Agents capture learnings, auto-clustered into insights |
81
- | **Review Process** | Every task has an assignee + reviewer — nothing ships without a second set of eyes |
82
- | **Inbox System** | Per-agent message queues for async coordination |
83
- | **UI Kit** | Living design reference at `/ui-kit` — tokens, components, states |
84
- | **Content Negotiation** | `/bootstrap` serves HTML to browsers, markdown to agents (via Accept header) |
41
+ - **Start local:** run the install commands above, then open http://127.0.0.1:4445/dashboard
42
+ - **See it without installing (optional):** https://app.reflectt.ai/preview
43
+ - **Connect to cloud (optional):** get a join token at https://app.reflectt.ai and run:
44
+ ```bash
45
+ reflectt host connect --join-token <token> --cloud-url https://app.reflectt.ai
46
+ ```
85
47
 
86
- ## Deploy Anywhere
48
+ Docs: https://docs.reflectt.ai/
87
49
 
88
- reflectt-node is **stateful** — it stores data in SQLite + JSONL files. It needs persistent storage.
50
+ ## 60-second demo (defensible claim)
51
+ **In under 60 seconds, a human can answer:** what’s being worked on, by whom, what’s blocked, and what needs review — from the product UI.
89
52
 
90
- | Platform | Works | Notes |
91
- |----------|-------|-------|
92
- | Mac / Linux / Pi | ✅ | Node.js 22+ required |
93
- | Docker | ✅ | Mount a volume for `/data` |
94
- | Fly.io | ✅ | Persistent volume, ~$3-5/mo |
95
- | Railway / Render | ✅ | Any container host with volumes |
96
- | VPS ($5/mo) | ✅ | Ideal for always-on teams |
97
- | Cloudflare Workers | ❌ | No persistent filesystem |
98
- | AWS Lambda | ❌ | No persistent filesystem |
53
+ Self-host demo (default first-run URLs):
54
+ - Tasks: http://127.0.0.1:4445/tasks
55
+ - Agents: http://127.0.0.1:4445/agents
56
+ - Reviews: http://127.0.0.1:4445/reviews
99
57
 
100
- ## Cloud Sync (Optional)
58
+ Cloud demo: https://app.reflectt.ai/preview
101
59
 
102
- Connect to [Reflectt Cloud](https://app.reflectt.ai) to see all your teams in one dashboard:
60
+ One-line close: coordination primitives, not another agent framework.
103
61
 
104
- ```bash
105
- reflectt host connect --join-token <token>
62
+ **Tell your agent to bootstrap:**
63
+ ```
64
+ Follow the instructions at reflectt.ai/bootstrap
106
65
  ```
107
-
108
- Self-hosted nodes sync tasks, presence, and health to the cloud control plane. Free. Optional.
109
66
 
110
67
  ---
111
68
 
112
- ## API Quick Reference
113
-
114
- ```bash
115
- # Health check
116
- curl http://localhost:4445/health
117
-
118
- # List tasks
119
- curl http://localhost:4445/tasks
69
+ ## What it gives your agents
120
70
 
121
- # Create a task
122
- curl -X POST http://localhost:4445/tasks \
123
- -H 'Content-Type: application/json' \
124
- -d '{"title": "Ship the feature", "assignee": "link", "priority": "P1"}'
71
+ - **Shared task board** — one source of truth. Agents claim tasks, nothing gets done twice.
72
+ - **Per-agent inboxes** async messaging between agents without going through you.
73
+ - **Presence + heartbeats** — the team knows who's active and what they're working on.
74
+ - **Reflections** agents capture learnings after each task. Patterns surface as insights.
75
+ - **Live dashboard** — tasks, chat, health, reviews in one place.
76
+ - **REST + WebSocket API** — any agent in any framework can connect.
125
77
 
126
- # Get next task for an agent
127
- curl "http://localhost:4445/tasks/next?agent=link"
128
-
129
- # Send a chat message
130
- curl -X POST http://localhost:4445/chat/messages \
131
- -H 'Content-Type: application/json' \
132
- -d '{"from": "link", "content": "Done!", "channel": "general"}'
78
+ ---
133
79
 
134
- # Upload a file
135
- curl -X POST http://localhost:4445/files -F "file=@screenshot.png"
80
+ ## Connect to cloud (optional)
136
81
 
137
- # API discovery
138
- curl http://localhost:4445/capabilities
82
+ ```bash
83
+ reflectt host connect --join-token <token>
139
84
  ```
140
85
 
141
- **WebSocket:** `ws://localhost:4445/chat/ws`
142
-
143
- **Full API:** Every endpoint is discoverable at [`/capabilities`](http://localhost:4445/capabilities).
86
+ Get your token at [app.reflectt.ai](https://app.reflectt.ai). Your self-hosted node syncs to the cloud dashboard. Free. Optional.
144
87
 
145
88
  ---
146
89
 
147
- ## Configuration
90
+ ## Docker
148
91
 
149
92
  ```bash
150
- cp .env.example .env
93
+ docker run -d --name reflectt-node \
94
+ -p 4445:4445 \
95
+ -v reflectt-data:/data \
96
+ ghcr.io/reflectt/reflectt-node:latest
151
97
  ```
152
98
 
153
- | Variable | Default | Description |
154
- |----------|---------|-------------|
155
- | `PORT` | `4445` | Server port |
156
- | `HOST` | `127.0.0.1` | Bind address |
157
- | `OPENCLAW_GATEWAY_URL` | — | WebSocket URL for OpenClaw gateway |
158
- | `OPENCLAW_GATEWAY_TOKEN` | — | Auth token for gateway connection |
159
- | `SUPABASE_URL` | — | Enables cloud task sync |
160
- | `SUPABASE_SERVICE_ROLE_KEY` | — | Supabase service role key |
161
-
162
- ## Connect OpenClaw Agents
163
-
164
- ```bash
165
- openclaw plugins install ./plugins/reflectt-channel
166
- openclaw config set channels.reflectt.enabled true
167
- openclaw config set channels.reflectt.url "http://127.0.0.1:4445"
168
- openclaw gateway restart
169
- ```
99
+ ---
170
100
 
171
- ## Running Tests
101
+ ## API
172
102
 
173
103
  ```bash
174
- npm run build
175
- npm test # 1500+ tests
176
- ```
177
-
178
- ## Project Structure
179
-
180
- ```
181
- src/
182
- server.ts # Fastify server + routes
183
- dashboard.ts # Live dashboard (inline HTML/CSS/JS)
184
- tasks.ts # Task CRUD + state machine
185
- chat.ts # Chat + WebSocket
186
- health.ts # Team health + presence
187
- inbox.ts # Per-agent async inbox
188
- config.ts # Configuration
189
- types.ts # TypeScript types
190
-
191
- public/
192
- dashboard.js # Dashboard client-side JS
193
- bootstrap.md # Agent bootstrap instructions
104
+ curl http://localhost:4445/tasks # list tasks
105
+ curl "http://localhost:4445/tasks/next?agent=myagent" # next task for an agent
106
+ curl http://localhost:4445/inbox/myagent # agent inbox
107
+ curl http://localhost:4445/capabilities # full API reference
194
108
  ```
195
109
 
196
110
  ---
197
111
 
198
112
  ## Links
199
113
 
200
- - **Website:** [reflectt.ai](https://reflectt.ai)
201
- - **Cloud:** [app.reflectt.ai](https://app.reflectt.ai)
202
- - **Bootstrap:** [reflectt.ai/bootstrap](https://reflectt.ai/bootstrap)
203
- - **Discord:** [discord.gg/reflectt](https://discord.gg/reflectt)
114
+ - **Docs + bootstrap:** [reflectt.ai/bootstrap](https://reflectt.ai/bootstrap)
115
+ - **Cloud dashboard:** [app.reflectt.ai](https://app.reflectt.ai)
116
+ - **Discord:** [discord.gg/gMbWskMkbT](https://discord.gg/gMbWskMkbT)
204
117
 
205
118
  ## License
206
119
 
207
- Apache-2.0
208
-
209
- ---
210
-
211
- **Built by [Team Reflectt](https://reflectt.ai)** · Design by pixel 🎨
120
+ Apache-2.0 · [reflectt.ai](https://reflectt.ai)
@@ -37,4 +37,32 @@ export declare function getPreflightMetrics(): {
37
37
  };
38
38
  /** Reset metrics (for testing) */
39
39
  export declare function resetPreflightMetrics(): void;
40
+ /**
41
+ * Append a daily metrics snapshot if the date has changed.
42
+ * Called from getPreflightMetrics() and also from the health endpoint.
43
+ * Idempotent per calendar day.
44
+ */
45
+ export declare function snapshotDailyMetrics(): void;
46
+ /**
47
+ * Start periodic auto-snapshot (hourly).
48
+ * Ensures daily snapshots happen even if no health endpoint is accessed.
49
+ */
50
+ export declare function startAutoSnapshot(): void;
51
+ /**
52
+ * Stop the auto-snapshot timer (for testing/cleanup).
53
+ */
54
+ export declare function stopAutoSnapshot(): void;
55
+ /**
56
+ * Read all daily snapshots for the observation window report.
57
+ */
58
+ export declare function getDailySnapshots(): Array<{
59
+ date: string;
60
+ totalChecked: number;
61
+ suppressed: number;
62
+ canaryFlagged: number;
63
+ latencyP95: number;
64
+ mode: string;
65
+ falsePositiveRate: number;
66
+ backfilled?: boolean;
67
+ }>;
40
68
  //# sourceMappingURL=alert-preflight.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"alert-preflight.d.ts","sourceRoot":"","sources":["../src/alert-preflight.ts"],"names":[],"mappings":"AAwBA,MAAM,WAAW,cAAc;IAC7B,MAAM,EAAE,MAAM,CAAA;IACd,SAAS,EAAE,MAAM,CAAA;IACjB,mDAAmD;IACnD,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,oDAAoD;IACpD,cAAc,CAAC,EAAE,MAAM,CAAA;IACvB,iDAAiD;IACjD,gBAAgB,CAAC,EAAE,MAAM,CAAA;IACzB,iDAAiD;IACjD,gBAAgB,CAAC,EAAE,MAAM,CAAA;IACzB,8CAA8C;IAC9C,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,2CAA2C;IAC3C,OAAO,CAAC,EAAE,MAAM,CAAA;CACjB;AAED,MAAM,WAAW,eAAe;IAC9B,OAAO,EAAE,OAAO,CAAA;IAChB,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,SAAS,EAAE,MAAM,CAAA;IACjB,aAAa,EAAE,MAAM,CAAA;IACrB,IAAI,EAAE,aAAa,CAAA;CACpB;AAED,MAAM,MAAM,aAAa,GAAG,QAAQ,GAAG,SAAS,GAAG,KAAK,CAAA;AAoCxD,wBAAgB,gBAAgB,IAAI,aAAa,CAIhD;AAID;;;GAGG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,cAAc,GAAG,eAAe,CAkDrE;AA6JD,wBAAgB,mBAAmB,IAAI;IACrC,YAAY,EAAE,MAAM,CAAA;IACpB,UAAU,EAAE,MAAM,CAAA;IAClB,aAAa,EAAE,MAAM,CAAA;IACrB,UAAU,EAAE,MAAM,CAAA;IAClB,IAAI,EAAE,aAAa,CAAA;CACpB,CAYA;AAED,kCAAkC;AAClC,wBAAgB,qBAAqB,IAAI,IAAI,CAM5C"}
1
+ {"version":3,"file":"alert-preflight.d.ts","sourceRoot":"","sources":["../src/alert-preflight.ts"],"names":[],"mappings":"AAwBA,MAAM,WAAW,cAAc;IAC7B,MAAM,EAAE,MAAM,CAAA;IACd,SAAS,EAAE,MAAM,CAAA;IACjB,mDAAmD;IACnD,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,oDAAoD;IACpD,cAAc,CAAC,EAAE,MAAM,CAAA;IACvB,iDAAiD;IACjD,gBAAgB,CAAC,EAAE,MAAM,CAAA;IACzB,iDAAiD;IACjD,gBAAgB,CAAC,EAAE,MAAM,CAAA;IACzB,8CAA8C;IAC9C,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,2CAA2C;IAC3C,OAAO,CAAC,EAAE,MAAM,CAAA;CACjB;AAED,MAAM,WAAW,eAAe;IAC9B,OAAO,EAAE,OAAO,CAAA;IAChB,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,SAAS,EAAE,MAAM,CAAA;IACjB,aAAa,EAAE,MAAM,CAAA;IACrB,IAAI,EAAE,aAAa,CAAA;CACpB;AAED,MAAM,MAAM,aAAa,GAAG,QAAQ,GAAG,SAAS,GAAG,KAAK,CAAA;AAoCxD,wBAAgB,gBAAgB,IAAI,aAAa,CAIhD;AAID;;;GAGG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,cAAc,GAAG,eAAe,CAkDrE;AA6JD,wBAAgB,mBAAmB,IAAI;IACrC,YAAY,EAAE,MAAM,CAAA;IACpB,UAAU,EAAE,MAAM,CAAA;IAClB,aAAa,EAAE,MAAM,CAAA;IACrB,UAAU,EAAE,MAAM,CAAA;IAClB,IAAI,EAAE,aAAa,CAAA;CACpB,CAYA;AAED,kCAAkC;AAClC,wBAAgB,qBAAqB,IAAI,IAAI,CAM5C;AAwGD;;;;GAIG;AACH,wBAAgB,oBAAoB,IAAI,IAAI,CA4B3C;AAED;;;GAGG;AACH,wBAAgB,iBAAiB,IAAI,IAAI,CAMxC;AAED;;GAEG;AACH,wBAAgB,gBAAgB,IAAI,IAAI,CAKvC;AAED;;GAEG;AACH,wBAAgB,iBAAiB,IAAI,KAAK,CAAC;IACzC,IAAI,EAAE,MAAM,CAAA;IACZ,YAAY,EAAE,MAAM,CAAA;IACpB,UAAU,EAAE,MAAM,CAAA;IAClB,aAAa,EAAE,MAAM,CAAA;IACrB,UAAU,EAAE,MAAM,CAAA;IAClB,IAAI,EAAE,MAAM,CAAA;IACZ,iBAAiB,EAAE,MAAM,CAAA;IACzB,UAAU,CAAC,EAAE,OAAO,CAAA;CACrB,CAAC,CASD"}
@@ -232,4 +232,182 @@ export function resetPreflightMetrics() {
232
232
  metrics.latencies = [];
233
233
  recentKeys.clear();
234
234
  }
235
+ // ── Persistent daily snapshots ─────────────────────────────────────────────
236
+ const DAILY_FILE = join(DATA_DIR, 'alert-preflight-daily.jsonl');
237
+ let lastSnapshotDate = '';
238
+ let snapshotTimer = null;
239
+ /**
240
+ * Initialize snapshot state from existing daily file and backfill
241
+ * missing days from the audit log. Called once on module load.
242
+ */
243
+ function initSnapshotState() {
244
+ try {
245
+ const { readFileSync, existsSync } = require('fs');
246
+ // Recover lastSnapshotDate so restarts don't duplicate today's entry
247
+ if (existsSync(DAILY_FILE)) {
248
+ const lines = readFileSync(DAILY_FILE, 'utf8').trim().split('\n').filter(Boolean);
249
+ if (lines.length > 0) {
250
+ const last = JSON.parse(lines[lines.length - 1]);
251
+ if (last.date)
252
+ lastSnapshotDate = last.date;
253
+ }
254
+ }
255
+ // Backfill missing days from audit log
256
+ backfillFromAuditLog();
257
+ }
258
+ catch {
259
+ // Non-fatal — best-effort initialization
260
+ }
261
+ }
262
+ /**
263
+ * Scan the audit log and generate daily snapshots for any dates
264
+ * that don't already have an entry in the daily file.
265
+ */
266
+ function backfillFromAuditLog() {
267
+ try {
268
+ const { readFileSync, existsSync } = require('fs');
269
+ if (!existsSync(AUDIT_FILE))
270
+ return;
271
+ const auditContent = readFileSync(AUDIT_FILE, 'utf8').trim();
272
+ if (!auditContent)
273
+ return;
274
+ // Collect existing snapshot dates
275
+ const existingDates = new Set();
276
+ if (existsSync(DAILY_FILE)) {
277
+ const dailyContent = readFileSync(DAILY_FILE, 'utf8').trim();
278
+ if (dailyContent) {
279
+ for (const line of dailyContent.split('\n')) {
280
+ try {
281
+ const entry = JSON.parse(line);
282
+ if (entry.date)
283
+ existingDates.add(entry.date);
284
+ }
285
+ catch { /* skip malformed */ }
286
+ }
287
+ }
288
+ }
289
+ // Aggregate audit entries by date
290
+ const byDate = new Map();
291
+ for (const line of auditContent.split('\n')) {
292
+ try {
293
+ const entry = JSON.parse(line);
294
+ const date = new Date(entry.ts).toISOString().slice(0, 10);
295
+ if (existingDates.has(date))
296
+ continue; // already have a snapshot
297
+ let day = byDate.get(date);
298
+ if (!day) {
299
+ day = { total: 0, flagged: 0, suppressed: 0 };
300
+ byDate.set(date, day);
301
+ }
302
+ day.total++;
303
+ if (entry.mode === 'canary' && !entry.proceed)
304
+ day.flagged++; // shouldn't happen, canary always proceeds
305
+ if (entry.category)
306
+ day.flagged++; // any categorized entry = would-be suppression
307
+ if (entry.mode === 'enforce' && !entry.proceed)
308
+ day.suppressed++;
309
+ }
310
+ catch { /* skip malformed */ }
311
+ }
312
+ // Write backfilled snapshots (sorted by date)
313
+ const dates = [...byDate.keys()].sort();
314
+ for (const date of dates) {
315
+ const day = byDate.get(date);
316
+ const snapshot = {
317
+ date,
318
+ ts: new Date(date + 'T23:59:59Z').getTime(),
319
+ totalChecked: day.total,
320
+ suppressed: day.suppressed,
321
+ canaryFlagged: day.flagged,
322
+ latencyP95: 0, // not available from audit log
323
+ mode: 'canary',
324
+ falsePositiveRate: day.total > 0
325
+ ? Math.round((day.flagged / day.total) * 10000) / 100
326
+ : 0,
327
+ backfilled: true,
328
+ };
329
+ try {
330
+ appendFileSync(DAILY_FILE, JSON.stringify(snapshot) + '\n');
331
+ existingDates.add(date);
332
+ lastSnapshotDate = date > lastSnapshotDate ? date : lastSnapshotDate;
333
+ }
334
+ catch { /* non-fatal */ }
335
+ }
336
+ }
337
+ catch {
338
+ // Non-fatal — best-effort backfill
339
+ }
340
+ }
341
+ /**
342
+ * Append a daily metrics snapshot if the date has changed.
343
+ * Called from getPreflightMetrics() and also from the health endpoint.
344
+ * Idempotent per calendar day.
345
+ */
346
+ export function snapshotDailyMetrics() {
347
+ const today = new Date().toISOString().slice(0, 10); // YYYY-MM-DD
348
+ if (today === lastSnapshotDate)
349
+ return;
350
+ if (metrics.totalChecked === 0)
351
+ return; // nothing to snapshot
352
+ const sorted = [...metrics.latencies].sort((a, b) => a - b);
353
+ const p95Index = Math.floor(sorted.length * 0.95);
354
+ const latencyP95 = sorted.length > 0 ? sorted[p95Index] ?? 0 : 0;
355
+ const snapshot = {
356
+ date: today,
357
+ ts: Date.now(),
358
+ totalChecked: metrics.totalChecked,
359
+ suppressed: metrics.suppressed,
360
+ canaryFlagged: metrics.canaryFlagged,
361
+ latencyP95: Math.round(latencyP95 * 100) / 100,
362
+ mode: getPreflightMode(),
363
+ falsePositiveRate: metrics.totalChecked > 0
364
+ ? Math.round((metrics.canaryFlagged / metrics.totalChecked) * 10000) / 100
365
+ : 0,
366
+ };
367
+ try {
368
+ appendFileSync(DAILY_FILE, JSON.stringify(snapshot) + '\n');
369
+ lastSnapshotDate = today;
370
+ }
371
+ catch {
372
+ // Non-fatal — best-effort persistence
373
+ }
374
+ }
375
+ /**
376
+ * Start periodic auto-snapshot (hourly).
377
+ * Ensures daily snapshots happen even if no health endpoint is accessed.
378
+ */
379
+ export function startAutoSnapshot() {
380
+ if (snapshotTimer)
381
+ return;
382
+ snapshotTimer = setInterval(() => {
383
+ snapshotDailyMetrics();
384
+ }, 60 * 60 * 1000); // 1 hour
385
+ snapshotTimer.unref(); // Don't prevent process exit
386
+ }
387
+ /**
388
+ * Stop the auto-snapshot timer (for testing/cleanup).
389
+ */
390
+ export function stopAutoSnapshot() {
391
+ if (snapshotTimer) {
392
+ clearInterval(snapshotTimer);
393
+ snapshotTimer = null;
394
+ }
395
+ }
396
+ /**
397
+ * Read all daily snapshots for the observation window report.
398
+ */
399
+ export function getDailySnapshots() {
400
+ try {
401
+ const { readFileSync } = require('fs');
402
+ const content = readFileSync(DAILY_FILE, 'utf8').trim();
403
+ if (!content)
404
+ return [];
405
+ return content.split('\n').map((line) => JSON.parse(line));
406
+ }
407
+ catch {
408
+ return [];
409
+ }
410
+ }
411
+ // Initialize on module load
412
+ initSnapshotState();
235
413
  //# sourceMappingURL=alert-preflight.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"alert-preflight.js","sourceRoot":"","sources":["../src/alert-preflight.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"alert-preflight.js","sourceRoot":"","sources":["../src/alert-preflight.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"boardHealthWorker.d.ts","sourceRoot":"","sources":["../src/boardHealthWorker.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"boardHealthWorker.d.ts","sourceRoot":"","sources":["../src/boardHealthWorker.ts"],"names":[],"mappings":"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"}
@@ -16,7 +16,7 @@ import { validateTaskTimestamp, verifyTaskExists } from './health.js';
16
16
  import { policyManager } from './policy.js';
17
17
  import { getEffectiveActivity } from './activity-signal.js';
18
18
  import { presenceManager } from './presence.js';
19
- import { suggestReviewer } from './assignment.js';
19
+ import { suggestReviewer, getAgentRoles } from './assignment.js';
20
20
  import { isTestHarnessTask } from './test-task-filter.js';
21
21
  import { recordSystemLoopTick } from './system-loop-state.js';
22
22
  const DEFAULT_CONFIG = {
@@ -125,14 +125,9 @@ export class BoardHealthWorker {
125
125
  // 3a. Review SLA auto-reassignment
126
126
  const reviewActions = await this.checkReviewSla(now, dryRun);
127
127
  actions.push(...reviewActions);
128
- // 3b. Reflection automation nudges
129
- if (!dryRun) {
130
- try {
131
- const { tickReflectionNudges } = await import('./reflection-automation.js');
132
- await tickReflectionNudges();
133
- }
134
- catch { /* reflection automation may not be loaded */ }
135
- }
128
+ // 3b. Reflection automation nudges — handled by continuity loop (step 3e) to avoid
129
+ // duplicate fires. tickReflectionNudges() was previously called here AND inside
130
+ // tickContinuityLoop(), causing 2–3x duplicate messages per tick.
136
131
  // 3c. Working contract enforcement (auto-requeue stale doing tasks)
137
132
  if (!dryRun) {
138
133
  try {
@@ -334,7 +329,18 @@ export class BoardHealthWorker {
334
329
  if (!rqf?.enabled)
335
330
  return [];
336
331
  const actions = [];
337
- for (const agent of rqf.agents) {
332
+ const agents = (rqf.agents && rqf.agents.length > 0)
333
+ ? rqf.agents
334
+ : getAgentRoles().map(r => r.name);
335
+ // Reuse idle-nudge exclusions as a sensible default for ready-queue monitoring too.
336
+ // (Prevents pinging humans/diagnostics accounts.)
337
+ const excluded = new Set((policy.idleNudge?.excluded || []).map(a => String(a).toLowerCase()));
338
+ for (const agentRaw of agents) {
339
+ const agent = String(agentRaw || '').trim();
340
+ if (!agent)
341
+ continue;
342
+ if (excluded.has(agent.toLowerCase()))
343
+ continue;
338
344
  // Count unblocked todo tasks for this agent
339
345
  const todoTasks = taskManager.listTasks({ status: 'todo', assignee: agent });
340
346
  const unblockedTodo = todoTasks.filter(t => {
@@ -385,7 +391,7 @@ export class BoardHealthWorker {
385
391
  // Snapshot timestamp for freshness judgment
386
392
  const snapshotTime = new Date(now).toISOString().replace('T', ' ').slice(0, 19) + ' UTC';
387
393
  const msg = isBreach
388
- ? `⚠️ Ready-queue floor (idle): @${agent} has ${readyCount}/${rqf.minReady} unblocked todo tasks (need ${deficit} more). @sage @pixel — please spec/assign tasks to keep engineering lane fed.${breakdown}\n 🕐 snapshot: ${snapshotTime}`
394
+ ? `⚠️ Ready-queue floor (idle): @${agent} has ${readyCount}/${rqf.minReady} unblocked todo tasks (need ${deficit} more). Please spec/assign tasks to keep the lane fed.${breakdown}\n 🕐 snapshot: ${snapshotTime}`
389
395
  : `ℹ️ Ready-queue in-flight: @${agent} is active (doing=${doingTasks.length}, validating=${validatingTasks.length}). In validating, next task suggested via /tasks/next. Queue below floor (unblocked todo=${readyCount}, floor=${rqf.minReady}, need ${deficit} more).${breakdown}\n 🕐 snapshot: ${snapshotTime}`;
390
396
  if (!dryRun) {
391
397
  try {
@@ -496,7 +502,14 @@ export class BoardHealthWorker {
496
502
  if (now - lastReplenish < cooldownMs)
497
503
  continue;
498
504
  // Count unblocked todo tasks for this agent
499
- const todoTasks = taskManager.listTasks({ status: 'todo', assignee: agent });
505
+ // Use metadata.lane if present, fall back to assignee match
506
+ const allTodo = taskManager.listTasks({ status: 'todo' });
507
+ const todoTasks = allTodo.filter(t => {
508
+ const taskLane = t.metadata?.lane;
509
+ if (taskLane)
510
+ return taskLane === lane.name && t.assignee === agent;
511
+ return t.assignee === agent;
512
+ });
500
513
  const unblockedTodo = todoTasks.filter(t => {
501
514
  const blocked = t.metadata?.blocked_by;
502
515
  if (!blocked)