@hypercarrier/rarebit 0.1.0-alpha.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (50) hide show
  1. package/AGENTS.md +14 -0
  2. package/CHANGELOG.md +10 -0
  3. package/LICENSE +21 -0
  4. package/README.md +142 -0
  5. package/RUNBOOK.md +36 -0
  6. package/SECURITY.md +11 -0
  7. package/VISUAL-LANGUAGE.md +89 -0
  8. package/bin/rarebit.mjs +20 -0
  9. package/package.json +96 -0
  10. package/schemas/rarebit.schema.json +618 -0
  11. package/scripts/e2e-recall-pi083.mjs +199 -0
  12. package/scripts/e2e-summary-cache.mjs +257 -0
  13. package/scripts/verify-package.mjs +81 -0
  14. package/src/automatic-summary-policy.mjs +210 -0
  15. package/src/extension.mjs +516 -0
  16. package/src/herdr-activity.mjs +111 -0
  17. package/src/index.mjs +13 -0
  18. package/src/lifecycle.mjs +322 -0
  19. package/src/rarebit-activity.mjs +48 -0
  20. package/src/rarebit-artifact-state.mjs +839 -0
  21. package/src/rarebit-cli.mjs +305 -0
  22. package/src/rarebit-command.mjs +281 -0
  23. package/src/rarebit-core.mjs +525 -0
  24. package/src/rarebit-model.mjs +226 -0
  25. package/src/rarebit-recall.mjs +182 -0
  26. package/src/rarebit-service.mjs +579 -0
  27. package/src/rarebit-session.mjs +227 -0
  28. package/src/rarebit-settings.mjs +79 -0
  29. package/src/rarebit-store.mjs +771 -0
  30. package/src/rarebit-visual-language.mjs +110 -0
  31. package/src/types.d.ts +601 -0
  32. package/test/automatic-summary-policy.test.mjs +476 -0
  33. package/test/extension-activity.test.mjs +73 -0
  34. package/test/fixtures/branch-mixed.json +117 -0
  35. package/test/fixtures/conformance-corpus.v1.json +306 -0
  36. package/test/fixtures/truncated-mixed.jsonl +2 -0
  37. package/test/herdr-activity.test.mjs +93 -0
  38. package/test/lifecycle-contract-independent.test.mjs +627 -0
  39. package/test/rarebit-activity.test.mjs +82 -0
  40. package/test/rarebit-artifact-state.test.mjs +440 -0
  41. package/test/rarebit-cli.test.mjs +222 -0
  42. package/test/rarebit-command.test.mjs +127 -0
  43. package/test/rarebit-core.test.mjs +461 -0
  44. package/test/rarebit-cross-consumer-conformance.test.mjs +150 -0
  45. package/test/rarebit-independent-contract.test.mjs +317 -0
  46. package/test/rarebit-recall.test.mjs +434 -0
  47. package/test/rarebit-sidecar-protocol.test.mjs +538 -0
  48. package/test/rarebit-visual-language.test.mjs +75 -0
  49. package/test/summary-attention-independent.test.mjs +172 -0
  50. package/test/types-history.ts +13 -0
@@ -0,0 +1,306 @@
1
+ {
2
+ "schemaVersion": 1,
3
+ "selectorVersion": "rarebit-selector-v1",
4
+ "purpose": "Human-reviewed semantic examples for comparing Rarebit and adjacent projections without using an implementation as the oracle.",
5
+ "capabilities": {
6
+ "strictRarebit": ["core", "cli", "pi_extension"],
7
+ "knownNonconformance": {
8
+ "timeline": "selects matching physical JSONL entries without resolving the active branch"
9
+ },
10
+ "notRarebitProjections": {
11
+ "live_detail_turns": "shows user messages and terminal assistant outcomes; it omits continuations and includes non-Rarebit terminal outcomes",
12
+ "traffic_outcomes": "shows operational user and assistant request outcomes, including truncated outcomes"
13
+ }
14
+ },
15
+ "cases": [
16
+ {
17
+ "id": "linear-prose-and-outcomes",
18
+ "description": "User prose, assistant continuation, and normal stop are Rarebits; tool traffic, hidden reasoning, and exceptional terminal outcomes are not.",
19
+ "records": [
20
+ {
21
+ "type": "session",
22
+ "version": 2,
23
+ "id": "session-linear",
24
+ "timestamp": "2026-01-01T00:00:00.000Z",
25
+ "cwd": "/example"
26
+ },
27
+ {
28
+ "type": "message",
29
+ "id": "u-linear",
30
+ "parentId": null,
31
+ "timestamp": "2026-01-01T00:00:01.000Z",
32
+ "producer": "owner",
33
+ "message": {
34
+ "role": "user",
35
+ "content": [
36
+ { "type": "text", "text": "Compare the candidate renderers." }
37
+ ]
38
+ }
39
+ },
40
+ {
41
+ "type": "message",
42
+ "id": "a-continuation",
43
+ "parentId": "u-linear",
44
+ "timestamp": "2026-01-01T00:00:02.000Z",
45
+ "message": {
46
+ "role": "assistant",
47
+ "timestamp": 1767225601500,
48
+ "stopReason": "toolUse",
49
+ "content": [
50
+ {
51
+ "type": "text",
52
+ "text": "I will measure the current baseline."
53
+ },
54
+ {
55
+ "type": "toolCall",
56
+ "id": "call-1",
57
+ "name": "benchmark",
58
+ "arguments": {}
59
+ }
60
+ ]
61
+ }
62
+ },
63
+ {
64
+ "type": "message",
65
+ "id": "tool-result",
66
+ "parentId": "a-continuation",
67
+ "timestamp": "2026-01-01T00:00:03.000Z",
68
+ "message": {
69
+ "role": "toolResult",
70
+ "toolCallId": "call-1",
71
+ "content": [{ "type": "text", "text": "machine result" }]
72
+ }
73
+ },
74
+ {
75
+ "type": "message",
76
+ "id": "a-error",
77
+ "parentId": "tool-result",
78
+ "timestamp": "2026-01-01T00:00:04.000Z",
79
+ "message": {
80
+ "role": "assistant",
81
+ "timestamp": 1767225603500,
82
+ "stopReason": "error",
83
+ "content": [{ "type": "text", "text": "The attempt failed." }]
84
+ }
85
+ },
86
+ {
87
+ "type": "message",
88
+ "id": "a-stop",
89
+ "parentId": "a-error",
90
+ "timestamp": "2026-01-01T00:00:05.000Z",
91
+ "message": {
92
+ "role": "assistant",
93
+ "timestamp": 1767225604500,
94
+ "stopReason": "stop",
95
+ "content": [
96
+ { "type": "thinking", "thinking": "hidden reasoning" },
97
+ { "type": "text", "text": "The baseline is ready for review." }
98
+ ]
99
+ }
100
+ }
101
+ ],
102
+ "expected": {
103
+ "activeBranchIds": [
104
+ "u-linear",
105
+ "a-continuation",
106
+ "tool-result",
107
+ "a-error",
108
+ "a-stop"
109
+ ],
110
+ "rarebits": [
111
+ {
112
+ "sourceEntryId": "u-linear",
113
+ "role": "user",
114
+ "outcome": "user",
115
+ "text": "Compare the candidate renderers."
116
+ },
117
+ {
118
+ "sourceEntryId": "a-continuation",
119
+ "role": "assistant",
120
+ "outcome": "continuation",
121
+ "text": "I will measure the current baseline."
122
+ },
123
+ {
124
+ "sourceEntryId": "a-stop",
125
+ "role": "assistant",
126
+ "outcome": "stop",
127
+ "text": "The baseline is ready for review."
128
+ }
129
+ ],
130
+ "excludedEntryIds": ["tool-result", "a-error"]
131
+ }
132
+ },
133
+ {
134
+ "id": "fork-compaction-and-resume",
135
+ "description": "The final entry is the active leaf. An abandoned fork and a compaction summary are not selected; messages before and after compaction remain eligible on the active lineage.",
136
+ "records": [
137
+ {
138
+ "type": "session",
139
+ "version": 2,
140
+ "id": "session-fork",
141
+ "timestamp": "2026-01-02T00:00:00.000Z",
142
+ "cwd": "/example"
143
+ },
144
+ {
145
+ "type": "message",
146
+ "id": "u-root",
147
+ "parentId": null,
148
+ "timestamp": "2026-01-02T00:00:01.000Z",
149
+ "message": {
150
+ "role": "user",
151
+ "content": "Start from the measured baseline."
152
+ }
153
+ },
154
+ {
155
+ "type": "message",
156
+ "id": "a-shared",
157
+ "parentId": "u-root",
158
+ "timestamp": "2026-01-02T00:00:02.000Z",
159
+ "message": {
160
+ "role": "assistant",
161
+ "stopReason": "toolUse",
162
+ "content": "I will inspect the trace."
163
+ }
164
+ },
165
+ {
166
+ "type": "message",
167
+ "id": "u-abandoned",
168
+ "parentId": "a-shared",
169
+ "timestamp": "2026-01-02T00:00:03.000Z",
170
+ "message": {
171
+ "role": "user",
172
+ "content": "Try the abandoned direction."
173
+ }
174
+ },
175
+ {
176
+ "type": "message",
177
+ "id": "a-abandoned",
178
+ "parentId": "u-abandoned",
179
+ "timestamp": "2026-01-02T00:00:04.000Z",
180
+ "message": {
181
+ "role": "assistant",
182
+ "stopReason": "stop",
183
+ "content": "Abandoned fork result."
184
+ }
185
+ },
186
+ {
187
+ "type": "message",
188
+ "id": "u-resumed",
189
+ "parentId": "a-shared",
190
+ "timestamp": "2026-01-02T00:00:05.000Z",
191
+ "message": {
192
+ "role": "user",
193
+ "content": "Resume on the shared branch."
194
+ }
195
+ },
196
+ {
197
+ "type": "compaction",
198
+ "id": "compact-active",
199
+ "parentId": "u-resumed",
200
+ "timestamp": "2026-01-02T00:00:06.000Z",
201
+ "summary": "Derived compaction text is not Rarebit evidence."
202
+ },
203
+ {
204
+ "type": "message",
205
+ "id": "a-active",
206
+ "parentId": "compact-active",
207
+ "timestamp": "2026-01-02T00:00:07.000Z",
208
+ "message": {
209
+ "role": "assistant",
210
+ "stopReason": "stop",
211
+ "content": "Active branch result."
212
+ }
213
+ }
214
+ ],
215
+ "expected": {
216
+ "activeBranchIds": [
217
+ "u-root",
218
+ "a-shared",
219
+ "u-resumed",
220
+ "compact-active",
221
+ "a-active"
222
+ ],
223
+ "rarebits": [
224
+ {
225
+ "sourceEntryId": "u-root",
226
+ "role": "user",
227
+ "outcome": "user",
228
+ "text": "Start from the measured baseline."
229
+ },
230
+ {
231
+ "sourceEntryId": "a-shared",
232
+ "role": "assistant",
233
+ "outcome": "continuation",
234
+ "text": "I will inspect the trace."
235
+ },
236
+ {
237
+ "sourceEntryId": "u-resumed",
238
+ "role": "user",
239
+ "outcome": "user",
240
+ "text": "Resume on the shared branch."
241
+ },
242
+ {
243
+ "sourceEntryId": "a-active",
244
+ "role": "assistant",
245
+ "outcome": "stop",
246
+ "text": "Active branch result."
247
+ }
248
+ ],
249
+ "excludedEntryIds": ["u-abandoned", "a-abandoned", "compact-active"]
250
+ }
251
+ }
252
+ ],
253
+ "failureCases": [
254
+ {
255
+ "id": "malformed-jsonl",
256
+ "description": "A complete prefix followed by malformed JSON is unavailable to strict Rarebit readers, never an empty successful selection.",
257
+ "lines": [
258
+ "{\"type\":\"session\",\"version\":2,\"id\":\"session-malformed\"}",
259
+ "{\"type\":\"message\",\"id\":\"u1\",\"parentId\":null,\"message\":{\"role\":\"user\",\"content\":\"complete prefix\"}}",
260
+ "{\"type\":\"message\",\"id\":\"truncated\""
261
+ ],
262
+ "expected": {
263
+ "strictStatus": "unavailable",
264
+ "reason": "malformed_jsonl",
265
+ "trafficDiagnostic": "malformed_jsonl"
266
+ }
267
+ },
268
+ {
269
+ "id": "missing-active-parent",
270
+ "description": "An active leaf whose parent is absent is unavailable rather than a guessed partial branch.",
271
+ "records": [
272
+ { "type": "session", "version": 2, "id": "session-missing-parent" },
273
+ {
274
+ "type": "message",
275
+ "id": "a-orphan",
276
+ "parentId": "missing-parent",
277
+ "message": {
278
+ "role": "assistant",
279
+ "stopReason": "stop",
280
+ "content": "orphan"
281
+ }
282
+ }
283
+ ],
284
+ "expected": {
285
+ "strictStatus": "unavailable",
286
+ "reason": "missing_parent"
287
+ }
288
+ },
289
+ {
290
+ "id": "scan-capped",
291
+ "description": "A consumer that did not inspect the complete required branch reports unavailable instead of a successful partial Rarebit set.",
292
+ "expected": {
293
+ "strictStatus": "unavailable",
294
+ "reason": "scan_capped"
295
+ }
296
+ },
297
+ {
298
+ "id": "source-unavailable",
299
+ "description": "An absent or unreadable source remains explicitly unavailable.",
300
+ "expected": {
301
+ "strictStatus": "unavailable",
302
+ "reason": "source_unavailable"
303
+ }
304
+ }
305
+ ]
306
+ }
@@ -0,0 +1,2 @@
1
+ {"type":"message","id":"valid-1","message":{"role":"assistant","stopReason":"stop","content":[{"type":"text","text":"valid"}]}}
2
+ {"type":"message","id":"truncated","message":{"role":"assistant","stopReason":"stop","content":[{"type":"text","text":"incomplete"
@@ -0,0 +1,93 @@
1
+ import assert from "node:assert/strict";
2
+ import test from "node:test";
3
+
4
+ import {
5
+ createHerdrActivityReporter,
6
+ herdrActivityTokens,
7
+ } from "../src/herdr-activity.mjs";
8
+
9
+ const activity = {
10
+ latestUser: { timestamp: "2026-07-26T12:00:00.000Z" },
11
+ latestAgentStop: { timestamp: "2026-07-26T10:58:00.000Z" },
12
+ };
13
+
14
+ test("Herdr activity tokens are wall-clock projections and reject unknown times", () => {
15
+ assert.deepEqual(
16
+ herdrActivityTokens(activity, Date.parse("2026-07-26T12:03:30.000Z")),
17
+ {
18
+ rarebit_user_age: "3m",
19
+ rarebit_stop_age: "1h 05m",
20
+ },
21
+ );
22
+ assert.deepEqual(
23
+ herdrActivityTokens(
24
+ {
25
+ latestUser: { timestamp: "not-a-time" },
26
+ latestAgentStop: { timestamp: null },
27
+ },
28
+ Date.parse("2026-07-26T12:03:30.000Z"),
29
+ ),
30
+ { rarebit_user_age: null, rarebit_stop_age: null },
31
+ );
32
+ });
33
+
34
+ test("Herdr activity tokens show days and whole hours after 24 hours", () => {
35
+ assert.deepEqual(
36
+ herdrActivityTokens(
37
+ {
38
+ latestUser: { timestamp: "2026-07-25T12:00:00.000Z" },
39
+ latestAgentStop: { timestamp: "2026-07-23T04:01:00.000Z" },
40
+ },
41
+ Date.parse("2026-07-26T12:00:00.000Z"),
42
+ ),
43
+ {
44
+ rarebit_user_age: "1d 0h",
45
+ rarebit_stop_age: "3d 7h",
46
+ },
47
+ );
48
+ });
49
+
50
+ test("Herdr reporter refreshes with TTL, applies only to Pi, and clears on shutdown", async () => {
51
+ const sent = [];
52
+ let scheduled;
53
+ let cleared;
54
+ const reporter = createHerdrActivityReporter({
55
+ env: {
56
+ HERDR_ENV: "1",
57
+ HERDR_SOCKET_PATH: "/tmp/herdr.sock",
58
+ HERDR_PANE_ID: "p1",
59
+ },
60
+ now: () => Date.parse("2026-07-26T12:03:30.000Z"),
61
+ send: async (_endpoint, request) => sent.push(request),
62
+ setIntervalFn: (callback, interval) => {
63
+ scheduled = { callback, interval, unref: () => {} };
64
+ return scheduled;
65
+ },
66
+ clearIntervalFn: (timer) => {
67
+ cleared = timer;
68
+ },
69
+ });
70
+
71
+ reporter.start(activity);
72
+ await Promise.resolve();
73
+ assert.equal(scheduled.interval, 30_000);
74
+ assert.deepEqual(sent[0].params, {
75
+ pane_id: "p1",
76
+ source: "rarebit:activity",
77
+ applies_to_source: "herdr:pi",
78
+ seq: sent[0].params.seq,
79
+ ttl_ms: 90_000,
80
+ tokens: { rarebit_user_age: "3m", rarebit_stop_age: "1h 05m" },
81
+ });
82
+
83
+ scheduled.callback();
84
+ await Promise.resolve();
85
+ assert.equal(sent.length, 2);
86
+ reporter.stop();
87
+ await Promise.resolve();
88
+ assert.equal(cleared, scheduled);
89
+ assert.deepEqual(sent.at(-1).params.tokens, {
90
+ rarebit_user_age: null,
91
+ rarebit_stop_age: null,
92
+ });
93
+ });