@hypercarrier/rarebit 0.5.0 → 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/AGENTS.md +1 -1
- package/CHANGELOG.md +14 -0
- package/README.md +10 -0
- package/RUNBOOK.md +7 -3
- package/package.json +5 -1
- package/test/helpers/selection-monitor.mjs +10 -0
- package/test/simulator-selection.test.mjs +31 -0
package/AGENTS.md
CHANGED
|
@@ -7,7 +7,7 @@ must not replace it or claim Task, Project, runtime, or delivery truth.
|
|
|
7
7
|
Keep the public surface small. Test CLI behavior, package boundaries, and Pi
|
|
8
8
|
installation paths. Do not add private-helper mocks, export-count tests,
|
|
9
9
|
coverage targets, or tautological snapshots. Run `npm ci`, `npm test`, and
|
|
10
|
-
`npm run verify:package` before a release
|
|
10
|
+
`npm run verify:package` before a release.
|
|
11
11
|
|
|
12
12
|
Do not record Session prose, provider credentials, Recall bundles, or private
|
|
13
13
|
paths in issues, fixtures, logs, or release records. `README.md` owns user
|
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,19 @@
|
|
|
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
|
+
|
|
11
|
+
## 0.5.1 — 2026-10-12
|
|
12
|
+
|
|
13
|
+
- Document the release privacy gate as the baseline range scan in `RUNBOOK.md`
|
|
14
|
+
and `AGENTS.md`. A change outside the npm `files` list ships on `main`
|
|
15
|
+
without a version.
|
|
16
|
+
|
|
3
17
|
## 0.5.0 — 2026-10-07
|
|
4
18
|
|
|
5
19
|
- Add `/rarebit btw [--rarebits] [--readonly] [question]`. It opens a
|
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/RUNBOOK.md
CHANGED
|
@@ -1,12 +1,16 @@
|
|
|
1
1
|
# Rarebit runbook
|
|
2
2
|
|
|
3
3
|
To release, merge the version bump and its [CHANGELOG.md](CHANGELOG.md) entry
|
|
4
|
-
to `main`, run
|
|
5
|
-
`
|
|
4
|
+
to `main`, run
|
|
5
|
+
`git-privacy-scan --ref HEAD --base "$(git config privacy.baseline)" range`,
|
|
6
|
+
then push tag `v<version>`. Any finding blocks the release; the pre-push hook
|
|
7
|
+
runs the same scan. The tag push runs
|
|
6
8
|
[`.github/workflows/publish.yml`](.github/workflows/publish.yml). It runs the
|
|
7
9
|
package gates, publishes one verified packed artifact with npm provenance, and
|
|
8
10
|
creates the GitHub Release. A prerelease version goes to npm `next`; any other
|
|
9
|
-
version goes to `latest`. Publication adds no commit.
|
|
11
|
+
version goes to `latest`. Publication adds no commit. A change outside the npm
|
|
12
|
+
`files` list, such as `claude-code/`, changes no package bytes: push it to
|
|
13
|
+
`main` without a version.
|
|
10
14
|
|
|
11
15
|
Set `rarebit.model` in global Pi settings or in a trusted Project's
|
|
12
16
|
`.pi/settings.json`. It must be `provider/model` or an object with `provider`
|
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
|
+
});
|