@hypercarrier/rarebit 0.5.1 → 0.5.2
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.
- package/CHANGELOG.md +8 -0
- package/README.md +10 -0
- package/package.json +5 -1
- package/test/helpers/selection-monitor.mjs +10 -0
- package/test/simulator-selection.test.mjs +31 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,13 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.5.2 — 2026-10-15
|
|
4
|
+
|
|
5
|
+
- Add a development-only simulator lane (`npm run test:sim`) that runs real
|
|
6
|
+
Rarebit selection, materialization, Recall, compaction and tree navigation on
|
|
7
|
+
the shared HyperCarrier Pi simulator. It needs the HyperCarrier workspace.
|
|
8
|
+
`sim/` is not in the npm package. The lane found no Rarebit product bug.
|
|
9
|
+
- Move the selection monitor tests into `test/`.
|
|
10
|
+
|
|
3
11
|
## 0.5.1 — 2026-10-12
|
|
4
12
|
|
|
5
13
|
- Document the release privacy gate as the baseline range scan in `RUNBOOK.md`
|
package/README.md
CHANGED
|
@@ -400,6 +400,16 @@ Use [GitHub Issues](https://github.com/deephbz/rarebit/issues) for normal
|
|
|
400
400
|
support. Include no Session prose, credentials, or Recall files in public
|
|
401
401
|
reports.
|
|
402
402
|
|
|
403
|
+
## Development verification
|
|
404
|
+
|
|
405
|
+
`npm ci && npm test` runs standalone unit and selection checks. The private
|
|
406
|
+
R&D simulator lane uses HC's shared `@hypercarrier/pi-sim`; it does not enter
|
|
407
|
+
Rarebit's root install or published artifact. Run `npm run test:sim` in the HC
|
|
408
|
+
workspace or set `HC_PI_SIM_PATH` to an installed simulator package root.
|
|
409
|
+
Run `npm run test:sim:campaign` for the longer seeded campaign.
|
|
410
|
+
[Simulator scope, setup, properties, replay, and results](sim/README.md) remain
|
|
411
|
+
repository-only development artifacts. No real provider credentials are needed.
|
|
412
|
+
|
|
403
413
|
## Release and source history
|
|
404
414
|
|
|
405
415
|
Rarebit is released from an immutable version tag by
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@hypercarrier/rarebit",
|
|
3
|
-
"version": "0.5.
|
|
3
|
+
"version": "0.5.2",
|
|
4
4
|
"description": "Sparse, provenance-bearing conversational evidence recovery for Pi sessions.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "HyperCarrier contributors",
|
|
@@ -29,6 +29,9 @@
|
|
|
29
29
|
},
|
|
30
30
|
"scripts": {
|
|
31
31
|
"test": "node --test test/*.test.mjs",
|
|
32
|
+
"test:sim": "node --test sim/*.test.mjs",
|
|
33
|
+
"test:sim:campaign": "RAREBIT_SIM_RUNS=100 node --test sim/*.test.mjs",
|
|
34
|
+
"test:sim:replay": "node sim/replay.mjs",
|
|
32
35
|
"test:e2e:tui": "node scripts/e2e-v020-pi.mjs",
|
|
33
36
|
"test:e2e:summary-cache": "node scripts/e2e-summary-cache.mjs",
|
|
34
37
|
"test:e2e:recall": "node scripts/e2e-recall-pi0842.mjs",
|
|
@@ -55,6 +58,7 @@
|
|
|
55
58
|
"@earendil-works/pi-coding-agent": "0.84.2",
|
|
56
59
|
"@earendil-works/pi-tui": "0.84.2",
|
|
57
60
|
"ajv": "^6.15.0",
|
|
61
|
+
"fast-check": "^4.10.2",
|
|
58
62
|
"typescript": "^5.9.3"
|
|
59
63
|
},
|
|
60
64
|
"pi": {
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
// Independent observation of the prose-selection contract; no simulator needed.
|
|
2
|
+
import assert from 'node:assert/strict';
|
|
3
|
+
export function expectedProse(branch) {
|
|
4
|
+
return branch.filter(e => e.type === 'message' && (e.message.role === 'user' || (e.message.role === 'assistant' && ['stop', 'toolUse'].includes(e.message.stopReason))))
|
|
5
|
+
.map(e => ({ id: e.id ?? e.message.id ?? null, text: typeof e.message.content === 'string' ? e.message.content : (e.message.content ?? []).filter(b => b.type === 'text' && typeof b.text === 'string').map(b => b.text).join('\n'), readable: typeof e.message.content === 'string' || (e.message.content ?? []).some(b => b.type === 'text' && typeof b.text === 'string') }))
|
|
6
|
+
.filter(e => e.readable).map(({ id, text }) => ({ id, text }));
|
|
7
|
+
}
|
|
8
|
+
export function checkSelection(selection, branch) {
|
|
9
|
+
assert.deepEqual(selection.occurrences.map(o => ({ id: o.sourceEntryId, text: o.text })), expectedProse(branch), 'R1 selection contract');
|
|
10
|
+
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import test from 'node:test';
|
|
2
|
+
import assert from 'node:assert/strict';
|
|
3
|
+
import fc from 'fast-check';
|
|
4
|
+
import { selectRarebits } from '../src/rarebit-core.mjs';
|
|
5
|
+
import { parseNativeSession, resolveActiveBranch } from '../src/rarebit-session.mjs';
|
|
6
|
+
import { checkSelection } from './helpers/selection-monitor.mjs';
|
|
7
|
+
|
|
8
|
+
test('R1 exhaustive role/outcome/content pairs; R8 old and current native formats', () => {
|
|
9
|
+
const entries = [];
|
|
10
|
+
for (const role of ['user', 'assistant', 'toolResult']) for (const stopReason of ['stop', 'toolUse', 'error', 'aborted', 'length', undefined]) for (const content of ['prose', [{ type: 'text', text: 'prose' }, { type: 'thinking', thinking: 'private reasoning' }], [{ type: 'toolCall', id: 'synthetic', name: 'read', arguments: {} }], []]) entries.push({ type: 'message', message: { role, stopReason, content } });
|
|
11
|
+
let count = 0;
|
|
12
|
+
for (const a of entries) for (const b of entries) {
|
|
13
|
+
const branch = [a, b].map((e, i) => ({ ...e, id: `e${i}`, parentId: i ? 'e0' : null }));
|
|
14
|
+
checkSelection(selectRarebits(branch), branch); count++;
|
|
15
|
+
}
|
|
16
|
+
assert.equal(count, 5184);
|
|
17
|
+
for (const version of [1, 2, 3]) {
|
|
18
|
+
const branch = entries.map((e, i) => ({ ...e, id: `e${i}`, parentId: i ? `e${i-1}` : null, legacyExtra: 'retained' }));
|
|
19
|
+
const original = JSON.stringify([{ type: 'session', id: 'synthetic-old', version }, ...branch]);
|
|
20
|
+
const parsed = parseNativeSession(JSON.parse(original).map(e => JSON.stringify(e)).join('\n'));
|
|
21
|
+
checkSelection(selectRarebits(resolveActiveBranch(parsed)), branch);
|
|
22
|
+
assert.equal(JSON.stringify([parsed.header, ...parsed.entries]), original, 'R8 no read-time migration');
|
|
23
|
+
}
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
test('R1/R8 fast-check mixed native evidence with shrinking', () => {
|
|
27
|
+
fc.assert(fc.property(fc.array(fc.record({ role: fc.constantFrom('user', 'assistant', 'toolResult'), stopReason: fc.constantFrom('stop', 'toolUse', 'error', 'aborted'), text: fc.string({ maxLength: 100 }) }), { maxLength: 30 }), records => {
|
|
28
|
+
const branch = records.map((r, i) => ({ type: 'message', id: `e${i}`, parentId: i ? `e${i-1}` : null, message: { role: r.role, stopReason: r.stopReason, content: [{ type: 'text', text: r.text }] } }));
|
|
29
|
+
checkSelection(selectRarebits(branch), branch);
|
|
30
|
+
}), { seed: 20261015, numRuns: 100 });
|
|
31
|
+
});
|