Build context-priority local CLI and brutalist launch demo

This commit is contained in:
codex committed 2026-10-10 17:30:20 -07:00
1 parent 70b7a8bbcd
commit 090400a95e
26 files changed
+759

No files matched your search

+47
View File
@@ -0,0 +1,47 @@
# Context Priority
Local, deterministic transcript selection. Keep critical exchanges verbatim instead of letting recent tangents take the whole continuation budget. No model calls, uploads, live compaction or runtime dependencies.
The board references [claude-code #83489](https://github.com/anthropics/claude-code/issues/83489), which requests named model/effort presets. This tool implements the board's **separate context-priority brief**, not that upstream feature.
## Install and use
Download `site/context-priority.zip`, unzip, and run from the extracted directory. Requires Node 20+. No npm install. macOS, Linux and Colima use the same commands:
```sh
node cli.cjs annotate sample.jsonl priorities.json e001=pinned e003=aside
node cli.cjs export sample.jsonl priorities.json 1000 ./out
node --test tests/*.test.cjs
```
`annotate` prints the exchange count; IDs are e001, e002… in source order. Unannotated exchanges default to normal. To change priorities, rerun annotate with the complete desired mapping. Existing sidecars and outputs require a terminal and explicit `OVERWRITE`; noninteractive overwrite is refused. No force flag. The source is never opened for writing. Outputs use private file permissions. Back up sensitive source files yourself.
`out/continuation.md` contains complete exchanges in chronological order inside JSONL code blocks. Pinned JSONL payloads retain their original whitespace and line endings, without paraphrasing. `out/omissions.json` lists every exchange, priority, framed byte cost, selected/omitted status, reason and source SHA-256. Annotations are separate JSON with `version:1`, `sourceSha256`, `priorities`. A changed source invalidates its sidecar.
## Input contract
UTF-8 JSONL, one ordered message per line, no blank lines. Supported records:
- `{ "role":"user", "content":"prompt" }`, assistant records, and `{ "role":"tool", "tool_call_id":"id", "content":"result" }`.
- Assistant `tool_calls` IDs paired with tool `tool_call_id`.
- Message-wrapped `{ "type":"user", "message":{ "role":"user", "content": [...] } }` / assistant records; content blocks may include `tool_use` with `id` and `tool_result` with `tool_use_id`.
An exchange starts at a user prompt and ends with an assistant response before the next user prompt. Result-only user records belong to the ongoing exchange. All tool calls must have matching results in the same exchange. Orphaned results, outstanding calls, a final user prompt, missing final assistant response, mixed result/text user blocks, unsupported roles and metadata records fail closed. This is a strict subset of exported JSONL, **not a universal Claude export importer**. Normalize linear message history first; do not feed a branching raw session log.
## Selection and limits
`site/engine.js` is the exact same module used by CLI and browser. All pinned exchanges are reserved first. A budget below the pinned content plus Markdown framing is rejected. Then normal exchanges are considered oldest-first, then asides oldest-first, skipping whole exchanges that do not fit. Output restores source chronology. The UTF-8 byte budget includes the full Markdown packet, **not the manifest**, and is not a token count. No exchange splitting, summarization or semantic dependency detection. Separate exchanges may reference omitted material: inspect before continuing. Fences grow to safely contain literal backticks.
Export stages both artifacts before publishing. A process or filesystem failure during the two renames can leave one new output and one old output; this is not a transactional two-file replace. Remaining staged artifacts stay in the reported `.context-priority-*` directory for recovery. Output aliases of the source/sidecar, symlink files and hard-linked output files are refused. Concurrent writers to the same output directory are unsupported; use a fresh directory per run. No secrets are redacted: exported content is as sensitive as the source.
## Browser demo / launch
Open `site/index.html` locally. Only the bundled synthetic transcript is demonstrated: no upload control, no network calls from the demo, no external scripts/fonts/trackers. Change priorities or byte budget; download the packet and omission manifest. The free CLI zip remains available without signup. Signup is a plain POST to the existing `/api/signup` service and therefore needs the published route; it does not work from `file://`. Successful `?joined=1#join` displays thanks. Paid tiers are unbuilt founding-price ideas with no checkout.
Generate the download after source changes:
```sh
python3 build.py
```
The build includes only CLI, engine, sample, README and core/CLI tests. Screenshots and test receipts are in `evidence/`. There is no Fly, Boring, model preset or live session integration. Publishing is handled by the existing runner after the issue reply.
+12
View File
@@ -0,0 +1,12 @@
"""Build a deterministic, dependency-free download; no shared files modified."""
from pathlib import Path
from zipfile import ZipFile, ZipInfo, ZIP_DEFLATED
root = Path(__file__).resolve().parent
files = ['README.md', 'cli.cjs', 'sample.jsonl', 'site/engine.js', 'tests/core.test.cjs', 'tests/cli.test.cjs']
with ZipFile(root / 'site/context-priority.zip', 'w') as archive:
for name in sorted(files):
entry = ZipInfo('context-priority/' + name, date_time=(2026, 10, 10, 0, 0, 0))
entry.compress_type = ZIP_DEFLATED
entry.external_attr = 0o100644 << 16
archive.writestr(entry, (root / name).read_bytes())
print('Built site/context-priority.zip')
+74
View File
@@ -0,0 +1,74 @@
#!/usr/bin/env node
'use strict';
const fs = require('node:fs');
const path = require('node:path');
const crypto = require('node:crypto');
const readline = require('node:readline/promises');
const engine = require('./site/engine.js');
const usage = `Usage (Node 20+):
node cli.cjs annotate SOURCE.jsonl SIDECAR.json [e001=pinned e002=aside ...]
node cli.cjs export SOURCE.jsonl SIDECAR.json BUDGET_BYTES NEW_OUTPUT_DIR
Outputs: continuation.md + omissions.json. Existing files require interactive confirmation.
Budget includes all Markdown framing; source transcripts are never written.`;
function identity(file) { return path.resolve(file); }
async function confirm(files) {
if (!files.length) return;
if (!process.stdin.isTTY) throw Error('Output exists; rerun in a terminal to confirm overwrite');
const rl = readline.createInterface({input:process.stdin,output:process.stdout});
try { if (await rl.question('Overwrite ' + files.join(', ') + '? Type OVERWRITE: ') !== 'OVERWRITE') throw Error('Cancelled'); }
finally { rl.close(); }
}
function guard(file, protectedFiles) {
if (protectedFiles.includes(identity(file))) throw Error('Output would overwrite an input');
if (fs.existsSync(file)) {
const stat = fs.lstatSync(file);
if (!stat.isFile() || stat.nlink > 1) throw Error('Output must be a regular file with no hard links');
if (protectedFiles.some(p => fs.existsSync(p) && fs.realpathSync(p) === fs.realpathSync(file))) throw Error('Output aliases an input');
}
}
async function main() {
const [command, sourcePath, sidecarPath, ...rest] = process.argv.slice(2);
if (!['annotate','export'].includes(command) || !sourcePath || !sidecarPath) throw Error(usage);
const buffer = fs.readFileSync(sourcePath);
if (buffer.subarray(0,3).equals(Buffer.from([239,187,191]))) throw Error('UTF-8 BOM is unsupported; normalize the export first');
const source = new TextDecoder('utf-8', {fatal:true}).decode(buffer);
const exchanges = engine.parse(source);
const sha256 = crypto.createHash('sha256').update(buffer).digest('hex');
if (command === 'annotate') {
guard(sidecarPath, [identity(sourcePath)]);
const priorities = Object.fromEntries(rest.map(value => {
const parts = value.split('='); if (parts.length !== 2) throw Error('Use e001=pinned'); return parts;
}));
engine.select(exchanges, priorities, Number.MAX_SAFE_INTEGER);
const existed = fs.existsSync(sidecarPath);
await confirm(existed?[sidecarPath]:[]);
fs.writeFileSync(sidecarPath, JSON.stringify({version:1,sourceSha256:sha256,priorities},null,2)+'\n', {flag:existed?'w':'wx',mode:0o600});
console.log('Sidecar saved; '+exchanges.length+' complete exchanges. Source unchanged.');
} else {
if (rest.length !== 2 || !/^\d+$/.test(rest[0])) throw Error(usage);
const [budget, directory] = rest;
const sidecar = JSON.parse(fs.readFileSync(sidecarPath,'utf8'));
if (sidecar.version !== 1 || sidecar.sourceSha256 !== sha256) throw Error('Sidecar does not match this transcript');
const result = engine.select(exchanges, sidecar.priorities, Number(budget));
const outputs = ['continuation.md','omissions.json'].map(name => path.join(directory,name));
for (const file of outputs) guard(file, [identity(sourcePath),identity(sidecarPath)]);
const existing = new Set(outputs.filter(f => fs.existsSync(f)));
await confirm([...existing]);
// Build both artifacts in a private staging directory first. Leave it on publication failure.
fs.mkdirSync(directory,{recursive:true,mode:0o700});
const stage = fs.mkdtempSync(path.join(directory,'.context-priority-'));
fs.writeFileSync(path.join(stage,'continuation.md'),result.packet,{mode:0o600});
fs.writeFileSync(path.join(stage,'omissions.json'),JSON.stringify({...result.manifest,sourceSha256:sha256},null,2)+'\n',{mode:0o600});
try {
for (const file of outputs) {
guard(file,[identity(sourcePath),identity(sidecarPath)]);
const staged = path.join(stage,path.basename(file));
if (existing.has(file)) fs.renameSync(staged,file);
else { fs.linkSync(staged,file); fs.unlinkSync(staged); }
}
fs.rmdirSync(stage);
} catch (error) { throw Error(error.message+'; recover remaining artifacts from '+stage); }
console.log('Exported '+result.manifest.packetBytes+'/'+budget+' bytes to '+directory);
}
}
main().catch(error => { console.error(error.message); process.exitCode = 1; });
@@ -0,0 +1,13 @@
# Verification
- `macos-tests.txt`: native hb-5 Node v24.21.0 core/CLI tests.
- `bundle-tests.txt`: tests executed from the extracted free zip on macOS.
- `colima-tests.txt`: Node 20 Alpine CLI/core tests and synthetic export inside Colima.
- `browser.json`, `desktop.png`, `phone.png`: file:// Chromium checks in Colima; both screenshots visually inspected before landing.
- `desktop-packet.md`, `phone-packet.md` and manifests: exact browser download evidence.
- `signup-tests.txt`: real existing signup handler imported into an isolated temporary filesystem; form POST, record, 303 redirect, invalid email, honeypot, unpublished venture rejection. No production signup written.
- `macos-browser.txt`: native browser limitation, recorded separately.
- `interactive-confirmation.txt`: native synthetic PTY overwrite confirmation.
No public route request was made: the factory publishes after the issue reply.
All changes are confined to this venture. Browser test requires external development-only Playwright and `CHROME_PATH` if not using hb-5 Chrome; neither is a product dependency. Engine and CLI tests require only Node.
@@ -0,0 +1,22 @@
{
"platform": "linux",
"browser": "149.0.7827.53",
"viewports": [
"1280x900",
"390x844"
],
"route": "file:// site/index.html (publication happens after reply)",
"checks": [
"no horizontal overflow",
"shared engine parity",
"paired tool exchange",
"priority changes",
"pin budget refusal",
"packet + manifest + free bundle downloads",
"plain signup form",
"thank-you redirect state",
"no external requests",
"no JS errors"
],
"htmlSha256": "467ee72b09228237a4250ab821e6fb0d3403ee025eb48c3c7a22d187f72370b6"
}
@@ -0,0 +1,17 @@
✔ CLI export, hash guard, noninteractive overwrite refusal, source aliases and recovery-safe preflight (402.120875ms)
✔ parse four complete exchanges and preserve the exact source (0.535042ms)
✔ pins survive verbatim; whole tool exchange stays paired; chronological output (0.752875ms)
✔ pinned minimum is exact, and too-small budget refuses (0.314833ms)
✔ normal beats an earlier aside; oversized normal can be skipped whole (0.173834ms)
✔ bad priorities, budgets, incomplete exchanges and tool mismatches fail closed (0.348042ms)
✔ message-wrapped tool blocks belong to the same exchange (0.20375ms)
✔ fences grow around hostile Markdown and Unicode byte counts are exact (0.145084ms)
✔ selection is deterministic and leaves inputs intact (0.139583ms)
ℹ tests 9
ℹ suites 0
ℹ pass 9
ℹ fail 0
ℹ cancelled 0
ℹ skipped 0
ℹ todo 0
ℹ duration_ms 455.642458
@@ -0,0 +1,95 @@
v20.20.2
TAP version 13
# Subtest: CLI export, hash guard, noninteractive overwrite refusal, source aliases and recovery-safe preflight
ok 1 - CLI export, hash guard, noninteractive overwrite refusal, source aliases and recovery-safe preflight
---
duration_ms: 240.601139
...
# Subtest: parse four complete exchanges and preserve the exact source
ok 2 - parse four complete exchanges and preserve the exact source
---
duration_ms: 0.853188
...
# Subtest: pins survive verbatim; whole tool exchange stays paired; chronological output
ok 3 - pins survive verbatim; whole tool exchange stays paired; chronological output
---
duration_ms: 0.850521
...
# Subtest: pinned minimum is exact, and too-small budget refuses
ok 4 - pinned minimum is exact, and too-small budget refuses
---
duration_ms: 0.363449
...
# Subtest: normal beats an earlier aside; oversized normal can be skipped whole
ok 5 - normal beats an earlier aside; oversized normal can be skipped whole
---
duration_ms: 0.13583
...
# Subtest: bad priorities, budgets, incomplete exchanges and tool mismatches fail closed
ok 6 - bad priorities, budgets, incomplete exchanges and tool mismatches fail closed
---
duration_ms: 0.48778
...
# Subtest: message-wrapped tool blocks belong to the same exchange
ok 7 - message-wrapped tool blocks belong to the same exchange
---
duration_ms: 0.763273
...
# Subtest: fences grow around hostile Markdown and Unicode byte counts are exact
ok 8 - fences grow around hostile Markdown and Unicode byte counts are exact
---
duration_ms: 0.20612
...
# Subtest: selection is deterministic and leaves inputs intact
ok 9 - selection is deterministic and leaves inputs intact
---
duration_ms: 0.338159
...
1..9
# tests 9
# suites 0
# pass 9
# fail 0
# cancelled 0
# skipped 0
# todo 0
# duration_ms 317.386364
Sidecar saved; 4 complete exchanges. Source unchanged.
Exported 872/1000 bytes to /tmp/packet
{
"version": 1,
"budgetBytes": 1000,
"packetBytes": 872,
"ordering": "pinned first; normal next; aside last; oldest fitting first within tier; output chronological",
"exchanges": [
{
"id": "e001",
"priority": "pinned",
"bytes": 191,
"selected": true,
"reason": "selected"
},
{
"id": "e002",
"priority": "normal",
"bytes": 391,
"selected": true,
"reason": "selected"
},
{
"id": "e003",
"priority": "aside",
"bytes": 180,
"selected": false,
"reason": "budget"
},
{
"id": "e004",
"priority": "normal",
"bytes": 180,
"selected": true,
"reason": "selected"
}
],
"sourceSha256": "a4369c8a7234d9e8933e62f6643a73c59b571e267d8a65d668a1d827b72b43b5"
}
@@ -0,0 +1,36 @@
{
"version": 1,
"budgetBytes": 1000,
"packetBytes": 872,
"ordering": "pinned first; normal next; aside last; oldest fitting first within tier; output chronological",
"exchanges": [
{
"id": "e001",
"priority": "pinned",
"bytes": 191,
"selected": true,
"reason": "selected"
},
{
"id": "e002",
"priority": "normal",
"bytes": 391,
"selected": true,
"reason": "selected"
},
{
"id": "e003",
"priority": "aside",
"bytes": 180,
"selected": false,
"reason": "budget"
},
{
"id": "e004",
"priority": "normal",
"bytes": 180,
"selected": true,
"reason": "selected"
}
]
}
@@ -0,0 +1,27 @@
# Context priority continuation
Selected complete exchanges in original order. JSONL payloads are verbatim.
## e001
```jsonl
{"role":"user","content":"Ship a migration plan. Never delete customer records."}
{"role":"assistant","content":"Constraint accepted: preserve every customer record."}
```
## e002
```jsonl
{"role":"user","content":"Check the schema."}
{"role":"assistant","content":"Reading schema.","tool_calls":[{"id":"schema-1","type":"function","function":{"name":"read_file","arguments":"schema.sql"}}]}
{"role":"tool","tool_call_id":"schema-1","content":"customers(id, email, created_at)"}
{"role":"assistant","content":"Add the index concurrently; retain all rows."}
```
## e004
```jsonl
{"role":"user","content":"Continue with the rollback checklist."}
{"role":"assistant","content":"Rollback removes the new index only, never customer data."}
```
Binary file not shown.

After

Width:  |  Height:  |  Size: 468 KiB

@@ -0,0 +1,4 @@
Native hb-5 PTY: annotated a synthetic sample into a temporary sidecar.
Reran annotate against the existing sidecar: CLI paused at
"Overwrite ...? Type OVERWRITE: ". Sent OVERWRITE; CLI succeeded.
Noninteractive refusal, source immutability and alias guards also covered by CLI tests.
@@ -0,0 +1,5 @@
Native macOS Chrome: NOT VERIFIED. Both Playwright launch and the requested
Chrome --headless=new --window-size=1280,900 file:// screenshot command aborted
with SIGABRT before rendering under the seat sandbox. No native screenshot produced.
Desktop and phone were instead inspected in Colima Chromium 149.0.7827.53.
Native hb-5 Node v24.21.0 CLI/core and extracted-bundle tests passed.
@@ -0,0 +1,17 @@
✔ CLI export, hash guard, noninteractive overwrite refusal, source aliases and recovery-safe preflight (384.033125ms)
✔ parse four complete exchanges and preserve the exact source (0.61175ms)
✔ pins survive verbatim; whole tool exchange stays paired; chronological output (0.765375ms)
✔ pinned minimum is exact, and too-small budget refuses (0.316458ms)
✔ normal beats an earlier aside; oversized normal can be skipped whole (0.155917ms)
✔ bad priorities, budgets, incomplete exchanges and tool mismatches fail closed (0.324042ms)
✔ message-wrapped tool blocks belong to the same exchange (0.190083ms)
✔ fences grow around hostile Markdown and Unicode byte counts are exact (0.133375ms)
✔ selection is deterministic and leaves inputs intact (0.139167ms)
ℹ tests 9
ℹ suites 0
ℹ pass 9
ℹ fail 0
ℹ cancelled 0
ℹ skipped 0
ℹ todo 0
ℹ duration_ms 435.823875
@@ -0,0 +1,36 @@
{
"version": 1,
"budgetBytes": 1000,
"packetBytes": 872,
"ordering": "pinned first; normal next; aside last; oldest fitting first within tier; output chronological",
"exchanges": [
{
"id": "e001",
"priority": "pinned",
"bytes": 191,
"selected": true,
"reason": "selected"
},
{
"id": "e002",
"priority": "normal",
"bytes": 391,
"selected": true,
"reason": "selected"
},
{
"id": "e003",
"priority": "aside",
"bytes": 180,
"selected": false,
"reason": "budget"
},
{
"id": "e004",
"priority": "normal",
"bytes": 180,
"selected": true,
"reason": "selected"
}
]
}
@@ -0,0 +1,27 @@
# Context priority continuation
Selected complete exchanges in original order. JSONL payloads are verbatim.
## e001
```jsonl
{"role":"user","content":"Ship a migration plan. Never delete customer records."}
{"role":"assistant","content":"Constraint accepted: preserve every customer record."}
```
## e002
```jsonl
{"role":"user","content":"Check the schema."}
{"role":"assistant","content":"Reading schema.","tool_calls":[{"id":"schema-1","type":"function","function":{"name":"read_file","arguments":"schema.sql"}}]}
{"role":"tool","tool_call_id":"schema-1","content":"customers(id, email, created_at)"}
{"role":"assistant","content":"Add the index concurrently; retain all rows."}
```
## e004
```jsonl
{"role":"user","content":"Continue with the rollback checklist."}
{"role":"assistant","content":"Rollback removes the new index only, never customer data."}
```
Binary file not shown.

After

Width:  |  Height:  |  Size: 445 KiB

@@ -0,0 +1,5 @@
POST /api/signup 303
POST /api/signup 400
POST /api/signup 303
POST /api/signup 404
PASS: real handler, isolated form POST, 303 redirect, record, invalid email, honeypot and unpublished venture guard. No production data written.
+10
View File
@@ -0,0 +1,10 @@
{"role":"user","content":"Ship a migration plan. Never delete customer records."}
{"role":"assistant","content":"Constraint accepted: preserve every customer record."}
{"role":"user","content":"Check the schema."}
{"role":"assistant","content":"Reading schema.","tool_calls":[{"id":"schema-1","type":"function","function":{"name":"read_file","arguments":"schema.sql"}}]}
{"role":"tool","tool_call_id":"schema-1","content":"customers(id, email, created_at)"}
{"role":"assistant","content":"Add the index concurrently; retain all rows."}
{"role":"user","content":"Aside: what should the mascot wear?"}
{"role":"assistant","content":"A very large green hat. This does not affect the migration."}
{"role":"user","content":"Continue with the rollback checklist."}
{"role":"assistant","content":"Rollback removes the new index only, never customer data."}
Binary file not shown.
+44
View File
@@ -0,0 +1,44 @@
'use strict';
const sample = [
{role:'user',content:'Ship a migration plan. Never delete customer records.'},
{role:'assistant',content:'Constraint accepted: preserve every customer record.'},
{role:'user',content:'Check the schema.'},
{role:'assistant',content:'Reading schema.',tool_calls:[{id:'schema-1',type:'function',function:{name:'read_file',arguments:'schema.sql'}}]},
{role:'tool',tool_call_id:'schema-1',content:'customers(id, email, created_at)'},
{role:'assistant',content:'Add the index concurrently; retain all rows.'},
{role:'user',content:'Aside: what should the mascot wear?'},
{role:'assistant',content:'A very large green hat. This does not affect the migration.'},
{role:'user',content:'Continue with the rollback checklist.'},
{role:'assistant',content:'Rollback removes the new index only, never customer data.'}
].map(row=>JSON.stringify(row)).join('\n')+'\n';
const engine = ContextPriority;
const exchanges = engine.parse(sample);
const priorities = {e001:'pinned',e002:'normal',e003:'aside',e004:'normal'};
const labels = ['Customer data constraint','Schema + tool call/result','Mascot tangent','Rollback checklist'];
let result;
const list = document.querySelector('#exchanges');
exchanges.forEach((exchange,index)=>{
const row=document.createElement('label'); row.className='exchange';
const text=document.createElement('span'); text.textContent=exchange.id+' / '+labels[index];
const select=document.createElement('select'); select.setAttribute('aria-label',labels[index]+' priority'); select.dataset.id=exchange.id;
for(const value of ['pinned','normal','aside']) {const option=document.createElement('option');option.value=value;option.textContent=value;select.append(option);}
select.value=priorities[exchange.id]; select.addEventListener('change',()=>{priorities[exchange.id]=select.value;render();});
row.append(text,select);list.append(row);
});
function render(){
result=null; document.querySelector('#download').disabled=true;document.querySelector('#manifest-download').disabled=true;
try {
result=engine.select(exchanges,priorities,Number(document.querySelector('#budget').value));
document.querySelector('#packet').textContent=result.packet;
document.querySelector('#manifest').textContent=JSON.stringify(result.manifest,null,2);
document.querySelector('#status').textContent=result.manifest.packetBytes+' bytes / '+result.manifest.exchanges.filter(e=>e.selected).length+' of 4 exchanges kept';
document.querySelector('#download').disabled=false; document.querySelector('#manifest-download').disabled=false;
}catch(error){document.querySelector('#packet').textContent='Export refused. Raise the budget or change your pins.';document.querySelector('#manifest').textContent='';document.querySelector('#status').textContent=error.message;}
}
function download(value,name,type){const url=URL.createObjectURL(new Blob([value],{type}));const a=document.createElement('a');a.href=url;a.download=name;a.click();setTimeout(()=>URL.revokeObjectURL(url),1000);}
document.querySelector('#budget').addEventListener('input',render);
document.querySelector('#download').addEventListener('click',()=>{if(result)download(result.packet,'continuation.md','text/markdown');});
document.querySelector('#manifest-download').addEventListener('click',()=>{if(result)download(JSON.stringify(result.manifest,null,2),'omissions.json','application/json');});
document.querySelector('#source').textContent=sample;
if(new URLSearchParams(location.search).get('joined')==='1'){document.querySelector('#thanks').hidden=false;document.querySelector('#join-form').hidden=true;}
render();
+70
View File
@@ -0,0 +1,70 @@
/* One deterministic engine, used by Node and the browser. No dependencies. */
(function (root) {
'use strict';
const bytes = s => new TextEncoder().encode(s).length;
const header = '# Context priority continuation\n\nSelected complete exchanges in original order. JSONL payloads are verbatim.\n\n';
function parse(source) {
if (typeof source !== 'string' || !source.trim()) throw Error('Empty transcript');
const exchanges = []; let current; let pending = new Set(); let assistant = false; let lastRole; let seenCalls = new Set();
function finish() {
if (!current) return;
if (!assistant || pending.size || lastRole !== 'assistant') throw Error('Incomplete exchange ' + current.id + ': missing assistant response or tool result');
exchanges.push(current);
}
for (const [index, raw] of (source.match(/[^\n]*\n|[^\n]+$/g) || []).entries()) {
if (!raw.trim()) throw Error('Blank line at ' + (index + 1));
let row; try { row = JSON.parse(raw); } catch { throw Error('Invalid JSON at line ' + (index + 1)); }
const msg = row.message || row;
const role = msg.role || row.type;
if (!['user', 'assistant', 'tool'].includes(role) || msg.content === undefined) throw Error('Unsupported record at line ' + (index + 1) + '; use user/assistant/tool JSONL');
const blocks = Array.isArray(msg.content) ? msg.content : [];
const results = blocks.filter(b => b.type === 'tool_result');
const resultOnly = role === 'tool' || (role === 'user' && blocks.length > 0 && results.length === blocks.length);
if (role === 'user' && !resultOnly) {
if (results.length) throw Error('Mixed user text and tool results: normalize this export first');
finish(); current = {id: 'e' + String(exchanges.length + 1).padStart(3, '0'), raw: ''}; pending = new Set(); assistant = false; seenCalls = new Set();
}
if (!current) throw Error('Transcript must start with a user prompt');
if (role === 'assistant') {
assistant = true;
const calls = [...(msg.tool_calls || []).map(c => c.id), ...blocks.filter(b => b.type === 'tool_use').map(b => b.id)];
for (const id of calls) {
if (typeof id !== 'string' || !id || seenCalls.has(id)) throw Error('Invalid or duplicate tool call');
pending.add(id); seenCalls.add(id);
}
}
const ids = role === 'tool' ? [msg.tool_call_id] : results.map(b => b.tool_use_id);
for (const id of ids) { if (!pending.delete(id)) throw Error('Unmatched tool result at line ' + (index + 1)); }
current.raw += raw; lastRole = role;
}
finish(); return exchanges;
}
function block(exchange) {
let length = 3;
for (const match of exchange.raw.matchAll(/`+/g)) length = Math.max(length, match[0].length + 1);
const fence = '`'.repeat(length);
return '## ' + exchange.id + '\n\n' + fence + 'jsonl\n' + exchange.raw + (exchange.raw.endsWith('\n') ? '' : '\n') + fence + '\n\n';
}
function select(exchanges, priorities, budget) {
if (!Number.isSafeInteger(budget) || budget < 0) throw Error('Budget must be a nonnegative integer of UTF-8 bytes');
if (!priorities || typeof priorities !== 'object' || Array.isArray(priorities)) throw Error('Invalid priorities');
const ids = new Set(exchanges.map(e => e.id));
for (const [id, priority] of Object.entries(priorities)) {
if (!ids.has(id) || !['pinned', 'normal', 'aside'].includes(priority)) throw Error('Invalid priority entry: ' + id);
}
const priority = e => priorities[e.id] || 'normal';
const selected = new Set(); const costs = new Map(exchanges.map(e => [e.id, bytes(block(e))]));
let used = bytes(header);
for (const e of exchanges.filter(e => priority(e) === 'pinned')) { selected.add(e.id); used += costs.get(e.id); }
if (used > budget) throw Error('Budget too small: pinned content and packet framing require ' + used + ' bytes');
for (const tier of ['normal','aside']) for (const e of exchanges.filter(e => priority(e) === tier)) {
if (used + costs.get(e.id) <= budget) { selected.add(e.id); used += costs.get(e.id); }
}
const packet = header + exchanges.filter(e => selected.has(e.id)).map(block).join('');
const manifest = {version: 1, budgetBytes: budget, packetBytes: bytes(packet), ordering: 'pinned first; normal next; aside last; oldest fitting first within tier; output chronological', exchanges: exchanges.map(e => ({id:e.id,priority:priority(e),bytes:costs.get(e.id),selected:selected.has(e.id),reason:selected.has(e.id)?'selected':'budget'}))};
return {packet,manifest};
}
const api = {parse,select,bytes,block};
if (typeof module !== 'undefined' && module.exports) module.exports = api;
else root.ContextPriority = api;
})(typeof globalThis !== 'undefined' ? globalThis : this);
+40
View File
@@ -0,0 +1,40 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1">
<meta name="description" content="Pin the exchanges that matter. A local, deterministic context selector with a free CLI and synthetic browser demo.">
<title>Context Priority — KEEP THE IMPORTANT PART.</title>
<style>
:root{--paper:#f4f1e7;--ink:#171713;--acid:#d7ff00;--orange:#fa5a25}*{box-sizing:border-box}html{scroll-behavior:smooth}body{margin:0;background:var(--paper);color:var(--ink);font-family:Georgia,'Times New Roman',serif}a{color:inherit;text-underline-offset:4px}button,input,select,textarea{font:inherit;border:2px solid var(--ink);border-radius:0;color:var(--ink);background:var(--paper)}button{padding:12px 18px;cursor:pointer;font-family:monospace;font-weight:bold}button:disabled{opacity:.4;cursor:default}a:focus-visible,button:focus-visible,input:focus-visible,select:focus-visible,textarea:focus-visible{outline:4px solid var(--orange);outline-offset:3px}[hidden]{display:none!important}.mast{display:flex;justify-content:space-between;gap:20px;padding:18px 3vw;border-bottom:3px solid;font:700 14px monospace;letter-spacing:1px}.mast span:last-child{text-align:right}.hero{display:grid;grid-template-columns:1.6fr 1fr;border-bottom:3px solid}.hero-title{padding:35px 3vw 40px;border-right:3px solid;overflow:hidden}.stamp{display:inline-block;background:var(--ink);color:var(--paper);padding:8px 12px;transform:rotate(-2deg);font:700 13px monospace}h1{font-family:Impact,'Arial Narrow',sans-serif;font-weight:900;font-size:clamp(64px,8.6vw,145px);letter-spacing:-.045em;line-height:.91;text-transform:uppercase;margin:30px 0 20px}h1 .keep{background:var(--acid);display:inline-block;padding:0 5px}h1 .part{color:var(--orange)}.hero-copy{padding:36px 3vw;display:flex;flex-direction:column;justify-content:space-between;gap:25px;background:var(--acid)}.eyebrow{font:700 13px monospace;text-transform:uppercase;letter-spacing:1px}.hero-copy p{font-size:24px;line-height:1.3;margin:0}.primary{display:block;padding:20px;background:var(--ink);color:var(--paper);font:bold 19px monospace;text-decoration:none;box-shadow:6px 6px 0 var(--orange)}.micro{font:13px/1.5 monospace}.ticker{background:var(--ink);color:var(--paper);padding:15px 3vw;font:bold 14px monospace;line-height:1.6}.section{padding:42px 3vw;border-bottom:3px solid}h2{font:900 clamp(36px,5vw,72px)/1 Impact,'Arial Narrow',sans-serif;text-transform:uppercase;letter-spacing:-1px;margin:12px 0 24px}h3{font:700 22px monospace;margin:0 0 15px}.demo-head{display:flex;justify-content:space-between;align-items:end;gap:30px}.budget{font:700 14px monospace;min-width:210px}.budget input{display:block;width:100%;padding:10px;margin-top:8px}.demo{display:grid;grid-template-columns:1fr 1.1fr;border:3px solid}.controls{padding:20px;border-right:3px solid}.exchange{display:flex;justify-content:space-between;align-items:center;gap:12px;border-bottom:2px solid;padding:18px 0;font:14px/1.5 monospace}.exchange select{padding:8px;flex-shrink:0}#status{padding:15px;background:var(--acid);font:bold 14px/1.5 monospace;min-height:64px}pre{font:12px/1.65 monospace;white-space:pre-wrap;overflow-wrap:anywhere;margin:0}#packet{height:360px;overflow:auto;padding:20px;background:#fffdf6}.actions{display:flex;flex-wrap:wrap;gap:10px;margin-top:20px}details{margin-top:20px;border-top:2px solid;padding-top:15px}summary{font:700 14px monospace;cursor:pointer}details pre{margin-top:15px}.how{display:grid;grid-template-columns:1fr 1.2fr;gap:35px}.how p,.limits p{font-size:20px;line-height:1.5}.terminal{background:var(--ink);color:var(--acid);padding:22px;border:3px solid var(--ink)}.download{font:bold 16px monospace;display:inline-block;border-bottom:3px solid;margin-top:15px}.prices{display:grid;grid-template-columns:repeat(3,1fr);border:3px solid}.price{padding:24px;border-right:3px solid}.price:last-child{border-right:0}.amount{font:900 46px Impact,'Arial Narrow',sans-serif;margin:20px 0}.price p{font-size:18px;line-height:1.5}.price .micro{font-size:13px}.join{display:grid;grid-template-columns:1fr 1fr;gap:40px;background:var(--orange)}#join-form{display:grid;gap:18px}#join-form label{font:700 14px monospace}#join-form input,#join-form select,#join-form textarea{display:block;padding:13px;width:100%;margin-top:7px}#join-form button{background:var(--ink);color:var(--paper);font-size:18px}#thanks{padding:22px;background:var(--acid);border:3px solid;font:700 22px/1.4 monospace}.limits{max-width:1000px}footer{display:flex;justify-content:space-between;gap:20px;padding:24px 3vw;font:13px/1.5 monospace}@media(max-width:700px){.mast{font-size:11px}.hero{grid-template-columns:1fr}.hero-title{border-right:0;border-bottom:3px solid;padding:28px 20px}.hero-copy{padding:25px 20px}.hero-copy p{font-size:22px}h1{font-size:clamp(60px,15vw,102px)}.section{padding:30px 20px}.demo-head{display:block}.budget{margin-bottom:20px}.demo,.how,.join,.prices{grid-template-columns:1fr}.controls{border-right:0;border-bottom:3px solid;padding:15px}.exchange{font-size:12px}.exchange select{max-width:110px}.price{border-right:0;border-bottom:3px solid}.price:last-child{border-bottom:0}#packet{height:300px}footer{display:block}footer span{display:block;margin:10px 0}}@media(prefers-reduced-motion:reduce){html{scroll-behavior:auto}}
</style>
<script defer src="engine.js"></script><script defer src="demo.js"></script>
</head>
<body>
<header class="mast"><span>CONTEXT PRIORITY / 001</span><span>A NOTPLANNED TOOL<br>LOCAL. DETERMINISTIC. YOUR CALL.</span></header>
<main>
<section class="hero">
<div class="hero-title"><span class="stamp">CONTEXT IS A FINITE RESOURCE.</span><h1><span class="keep">Keep</span> the<br>important<br><span class="part">part.</span></h1><div class="micro">PINNED → NORMAL → ASIDE<br>ONE ENGINE. NO MODEL CALLS.</div></div>
<div class="hero-copy"><div><div class="eyebrow">For people who work in long threads</div><p style="margin-top:20px">The constraint you wrote an hour ago should survive the tangent you wrote five minutes ago.</p><p style="margin-top:20px">Mark whole exchanges. Set a byte budget. Get a continuation packet you can inspect.</p></div><div><a class="primary" href="#join">GET EARLY ACCESS ↗</a><p class="micro" style="margin-top:18px">Free CLI available below. Paid plans are ideas, not a checkout.</p></div></div>
</section>
<div class="ticker">PINS STAY VERBATIM. TOOL PAIRS STAY TOGETHER. TOO SMALL A BUDGET? WE REFUSE THE EXPORT.</div>
<section class="section" id="demo"><div class="demo-head"><div><div class="eyebrow">01 / Try the actual selection engine</div><h2>Give the tangent<br>less room.</h2></div><label class="budget" for="budget">PACKET BUDGET / UTF-8 BYTES<input id="budget" type="number" min="0" step="50" value="1000"></label></div>
<p>Four synthetic exchanges. Change a priority and watch the packet change. Pin everything, then lower the budget to see a hard refusal. No transcript uploads.</p>
<div class="demo"><div class="controls"><h3>BEFORE / PRIORITIES</h3><div id="exchanges"></div><p class="micro">Oldest fitting exchange wins within each tier. Export restores chronology. This is a byte budget, not a model token count.</p><details><summary>Inspect untouched source JSONL</summary><pre id="source"></pre></details></div><div><div id="status" role="status" aria-live="polite">Loading synthetic demo…</div><pre id="packet" aria-label="Continuation packet"></pre></div></div>
<div class="actions"><button id="download" disabled>Download this packet ↓</button><button id="manifest-download" disabled>Download omission manifest ↓</button></div><details><summary>Inspect selection / omission manifest</summary><pre id="manifest"></pre></details><noscript><p>The interactive demo needs JavaScript. The free CLI below works offline.</p></noscript>
</section>
<section class="section"><div class="eyebrow">02 / Run it locally</div><h2>Your files. Your machine.</h2><div class="how"><div><p>No install scripts. No API key. Unzip the free bundle and use Node.js 20 or newer. Annotations live in a separate sidecar tied to the source SHA-256.</p><a class="download" href="context-priority.zip" download>DOWNLOAD FREE CLI (.zip) ↓</a><p class="micro">Includes source, sample, tests and README.<br>Verified on hb-5 macOS and Node 20 in Colima.</p></div><pre class="terminal"># From the extracted context-priority folder:
node cli.cjs annotate sample.jsonl priorities.json \
e001=pinned e003=aside
node cli.cjs export sample.jsonl priorities.json \
1000 ./out
# out/continuation.md + out/omissions.json
# Existing outputs require typing OVERWRITE.
# Run the checks:
node --test tests/*.test.cjs</pre></div></section>
<section class="section"><div class="eyebrow">03 / Founding plans — no checkout yet</div><h2>Start free. Tell us what’s next.</h2><div class="prices"><div class="price"><h3>LOCAL</h3><div class="amount">$0</div><p>The CLI, synthetic demo, sidecars and packet export. Available today.</p><div class="micro">NO ACCOUNT REQUIRED</div></div><div class="price"><h3>WORKBENCH</h3><div class="amount">$12 <small>/ mo</small></div><p>Proposed saved workflows and richer local import adapters.</p><div class="micro">FOUNDING PRICE IDEA · NOT BUILT</div></div><div class="price"><h3>TEAM</h3><div class="amount">$39 <small>/ mo</small></div><p>Proposed shared priority policies and reviewable packet history.</p><div class="micro">FOUNDING PRICE IDEA · NOT BUILT</div></div></div></section>
<section class="section join" id="join"><div><div class="eyebrow">04 / Join the early access list</div><h2>Help pick<br>the next<br>exchange.</h2><p>Choose the tier you’re interested in. No payment, no commitment.</p><p class="micro">We use your email for Context Priority launch updates and early access invitations.</p></div><div><div id="thanks" hidden>YOU’RE ON THE LIST.<br>Thanks. We’ll email when there’s something to try.</div><form id="join-form" method="post" action="/api/signup" enctype="application/x-www-form-urlencoded"><input type="hidden" name="venture" value="context-priority"><input type="hidden" name="website" value=""><label>Email<input type="email" name="email" required autocomplete="email" placeholder="you@example.com"></label><label>Interested tier<select name="plan"><option value="free">Local — free</option><option value="workbench">Workbench — $12/mo idea</option><option value="team">Team — $39/mo idea</option></select></label><label>What would make this useful? (optional)<textarea name="note" rows="3" maxlength="500"></textarea></label><button type="submit">JOIN EARLY ACCESS ↗</button></form></div></section>
<section class="section limits"><div class="eyebrow">05 / The fine print, in normal-sized type</div><h2>Selection. Not magic.</h2><p>This is a standalone offline selector, not live compaction and not an integration with Claude Code, Fly or Boring. It accepts ordered user/assistant/tool JSONL and message-wrapped user/assistant records; metadata rows, branching histories and incomplete exchanges are rejected. Normalize unsupported exports first. There is no tokenizer, summarizer, secret scrubber or semantic dependency analysis. Inspect the packet before sharing it.</p><p>Pinned payloads remain verbatim inside Markdown JSONL blocks. Unpinned exchanges can be omitted. The manifest tells you exactly which ones. A selected exchange keeps all its tool calls and results. Selection does not guarantee an assistant will obey the continuation.</p><p>The board’s upstream reference is <a href="https://github.com/anthropics/claude-code/issues/83489">anthropics/claude-code #83489: named model + effort presets</a>, closed as not planned. That issue asks for presets; this venture implements the board’s separate context-priority brief. It does not implement model presets and is not affiliated with Anthropic.</p></section>
</main><footer><span>CONTEXT PRIORITY / BUILT BY NOTPLANNED</span><span>PIN IT. INSPECT IT. CARRY IT FORWARD.</span></footer>
</body></html>
@@ -0,0 +1,33 @@
const {chromium}=require('playwright');const assert=require('node:assert/strict');const fs=require('node:fs');const path=require('node:path');const {pathToFileURL}=require('node:url');const engine=require('../site/engine.js');
(async()=>{
const out=path.resolve(__dirname,'../evidence');const url=pathToFileURL(path.resolve(__dirname,'../site/index.html')).href;
const browser=await chromium.launch({executablePath:process.env.CHROME_PATH || '/Applications/Google Chrome.app/Contents/MacOS/Google Chrome',args:['--no-sandbox']});const errors=[],external=[];
try {
for(const [name,width,height] of [['desktop',1280,900],['phone',390,844]]){
const page=await browser.newPage({viewport:{width,height},acceptDownloads:true});page.on('pageerror',e=>errors.push(e.message));page.on('request',r=>{if(/^https?:/.test(r.url()))external.push(r.url());});
await page.goto(url);await page.waitForFunction(()=>document.querySelector('#status').textContent.includes('exchanges kept'));
assert.equal(await page.evaluate(()=>document.documentElement.scrollWidth<=innerWidth),true);
const source=await page.locator('#source').textContent();const priorities={e001:'pinned',e002:'normal',e003:'aside',e004:'normal'};
assert.equal(await page.locator('#packet').textContent(),engine.select(engine.parse(source),priorities,1000).packet);
assert.match(await page.locator('#packet').textContent(),/tool_call_id/);assert.doesNotMatch(await page.locator('#packet').textContent(),/green hat/);
await page.screenshot({path:path.join(out,name+'.png'),fullPage:true});
for(const [selector,filename] of [['#download',name+'-packet.md'],['#manifest-download',name+'-manifest.json']]){
const [download]=await Promise.all([page.waitForEvent('download'),page.locator(selector).click()]);await download.saveAs(path.join(out,filename));
}
assert.equal(fs.readFileSync(path.join(out,name+'-packet.md'),'utf8'),await page.locator('#packet').textContent());
assert.equal(JSON.parse(fs.readFileSync(path.join(out,name+'-manifest.json'),'utf8')).packetBytes,Buffer.byteLength(fs.readFileSync(path.join(out,name+'-packet.md'),'utf8')));
await page.locator('select[data-id="e003"]').selectOption('pinned');assert.match(await page.locator('#packet').textContent(),/green hat/);
await page.locator('#budget').fill('100');assert.match(await page.locator('#status').textContent(),/Budget too small/);assert.equal(await page.locator('#download').isDisabled(),true);assert.equal(await page.locator('#manifest-download').isDisabled(),true);
await page.locator('#budget').fill('2000');assert.equal(await page.locator('#download').isDisabled(),false);
const form=await page.locator('#join-form').evaluate(f=>({method:f.method,action:f.getAttribute('action'),enctype:f.enctype,fields:Object.fromEntries(new FormData(f))}));
assert.equal(form.method,'post');assert.equal(form.action,'/api/signup');assert.equal(form.enctype,'application/x-www-form-urlencoded');assert.equal(form.fields.venture,'context-priority');assert.equal(form.fields.website,'');assert.equal(form.fields.plan,'free');
assert.equal(await page.locator('a[download]').getAttribute('href'),'context-priority.zip');
const [bundle]=await Promise.all([page.waitForEvent('download'),page.locator('a[download]').click()]);
const bundlePath='/tmp/priority-'+name+'-download.zip';await bundle.saveAs(bundlePath);
assert.deepEqual(fs.readFileSync(bundlePath),fs.readFileSync(path.resolve(__dirname,'../site/context-priority.zip')));
await page.goto(url+'?joined=1#join');assert.equal(await page.locator('#thanks').isVisible(),true);assert.equal(await page.locator('#join-form').isVisible(),false);await page.close();
}
assert.deepEqual(errors,[]);assert.deepEqual(external,[]);
fs.writeFileSync(path.join(out,'browser.json'),JSON.stringify({platform:process.platform,browser:await browser.version(),viewports:['1280x900','390x844'],route:'file:// site/index.html (publication happens after reply)',checks:['no horizontal overflow','shared engine parity','paired tool exchange','priority changes','pin budget refusal','packet + manifest + free bundle downloads','plain signup form','thank-you redirect state','no external requests','no JS errors'],htmlSha256:require('node:crypto').createHash('sha256').update(fs.readFileSync(path.resolve(__dirname,'../site/index.html'))).digest('hex')},null,2)+'\n');console.log('PASS: desktop and phone screenshots, download parity, pins, budget refusal, form, thank-you, no external requests or JS errors');
}finally{await browser.close();}
})().catch(e=>{console.error(e);process.exitCode=1;});
@@ -0,0 +1,24 @@
const test=require('node:test');const assert=require('node:assert/strict');const fs=require('node:fs');const os=require('node:os');const path=require('node:path');const {spawnSync}=require('node:child_process');
const cli=path.resolve(__dirname,'../cli.cjs');const sample=fs.readFileSync(path.resolve(__dirname,'../sample.jsonl'));
test('CLI export, hash guard, noninteractive overwrite refusal, source aliases and recovery-safe preflight',()=>{
const dir=fs.mkdtempSync(path.join(os.tmpdir(),'priority-test-'));
try {
const source=path.join(dir,'source.jsonl'),side=path.join(dir,'side.json'),out=path.join(dir,'out');fs.writeFileSync(source,sample);
const run=(...args)=>spawnSync(process.execPath,[cli,...args],{encoding:'utf8'});
assert.equal(run('annotate',source,side,'e001=pinned','e003=aside').status,0);
assert.equal(run('export',source,side,'1000',out).status,0);
const packet=fs.readFileSync(path.join(out,'continuation.md'));const manifest=JSON.parse(fs.readFileSync(path.join(out,'omissions.json')));
assert.equal(packet.length,manifest.packetBytes);assert.ok(packet.length<=1000);assert.ok(packet.includes(Buffer.from('Never delete customer records.')));
assert.equal(fs.statSync(path.join(out,'continuation.md')).mode&0o777,0o600);
assert.match(run('export',source,side,'1000',out).stderr,/terminal/);assert.deepEqual(fs.readFileSync(path.join(out,'continuation.md')),packet);
assert.match(run('annotate',source,side).stderr,/terminal/);
assert.match(run('annotate',source,source).stderr,/overwrite an input/);
const alias=path.join(dir,'alias.json');fs.symlinkSync(source,alias);assert.match(run('annotate',source,alias).stderr,/regular file/);
const hard=path.join(dir,'hard.json');fs.linkSync(source,hard);assert.match(run('annotate',source,hard).stderr,/regular file/);
assert.equal(run('export',source,side,'0',path.join(dir,'tiny')).status,1);assert.ok(!fs.existsSync(path.join(dir,'tiny')));
fs.appendFileSync(source,' ');assert.match(run('export',source,side,'1000',path.join(dir,'changed')).stderr,/Blank line|match/);
fs.writeFileSync(source,sample);assert.deepEqual(fs.readFileSync(source),sample);
const trap=path.join(dir,'trap');fs.mkdirSync(trap);fs.symlinkSync(source,path.join(trap,'omissions.json'));
assert.equal(run('export',source,side,'1000',trap).status,1);assert.ok(!fs.existsSync(path.join(trap,'continuation.md')));assert.deepEqual(fs.readFileSync(source),sample);
}finally{fs.rmSync(dir,{recursive:true,force:true});}
});
@@ -0,0 +1,49 @@
const test = require('node:test');
const assert = require('node:assert/strict');
const fs = require('node:fs');
const path = require('node:path');
const e = require('../site/engine.js');
const source = fs.readFileSync(path.join(__dirname,'../sample.jsonl'),'utf8');
const exchanges = e.parse(source);
test('parse four complete exchanges and preserve the exact source',()=>{
assert.equal(exchanges.length,4);assert.equal(exchanges.map(x=>x.raw).join(''),source);
assert.match(exchanges[1].raw,/tool_call_id/);
});
test('pins survive verbatim; whole tool exchange stays paired; chronological output',()=>{
const budget=e.bytes(e.select(exchanges,{e001:'pinned',e003:'aside'},99999).packet)-e.bytes(e.block(exchanges[2]));
const result=e.select(exchanges,{e001:'pinned',e003:'aside'},budget);
assert.deepEqual(result.manifest.exchanges.filter(x=>x.selected).map(x=>x.id),['e001','e002','e004']);
assert.ok(result.packet.includes(exchanges[0].raw));assert.ok(result.packet.includes(exchanges[1].raw));assert.ok(result.manifest.packetBytes<=budget);
assert.ok(result.packet.indexOf('## e001')<result.packet.indexOf('## e002'));
});
test('pinned minimum is exact, and too-small budget refuses',()=>{
const pinned=e.select([exchanges[1]],{e002:'pinned'},99999);
assert.throws(()=>e.select(exchanges,{e002:'pinned'},pinned.manifest.packetBytes-1),/Budget too small/);
const result=e.select(exchanges,{e002:'pinned'},pinned.manifest.packetBytes);
assert.deepEqual(result.manifest.exchanges.filter(x=>x.selected).map(x=>x.id),['e002']);
});
test('normal beats an earlier aside; oversized normal can be skipped whole',()=>{
const budget=e.select([exchanges[3]],{},99999).manifest.packetBytes;
const r=e.select(exchanges,{e001:'aside',e002:'normal',e003:'aside'},budget);
assert.deepEqual(r.manifest.exchanges.filter(x=>x.selected).map(x=>x.id),['e004']);
});
test('bad priorities, budgets, incomplete exchanges and tool mismatches fail closed',()=>{
for(const n of [-1,NaN,Infinity,1.5])assert.throws(()=>e.select(exchanges,{},n));
assert.throws(()=>e.select(exchanges,{e999:'pinned'},9999));assert.throws(()=>e.select(exchanges,{e001:'urgent'},9999));
for(const s of ['', '{broken', '{"role":"user","content":"hi"}\n', '{"type":"system","content":"metadata"}\n', source.replace('"tool_call_id":"schema-1"','"tool_call_id":"wrong"'), source.split('\n').filter(l=>!l.includes('"role":"tool"')).join('\n'), source.split('\n').slice(0,5).join('\n')]) assert.throws(()=>e.parse(s));
});
test('message-wrapped tool blocks belong to the same exchange',()=>{
const rows=[{type:'user',message:{role:'user',content:'read'}},{type:'assistant',message:{role:'assistant',content:[{type:'tool_use',id:'a',name:'read',input:{}}]}},{type:'user',message:{role:'user',content:[{type:'tool_result',tool_use_id:'a',content:'result'}]}},{type:'assistant',message:{role:'assistant',content:'done'}}];
const raw=rows.map(r=>JSON.stringify(r)).join('\r\n');
assert.equal(e.parse(raw).length,1);assert.equal(e.parse(raw)[0].raw,raw);
rows[2].message.content.push({type:'text',text:'new question'});assert.throws(()=>e.parse(rows.map(r=>JSON.stringify(r)).join('\n')),/Mixed/);
});
test('fences grow around hostile Markdown and Unicode byte counts are exact',()=>{
const raw='{"role":"user","content":"```` </script> 🍵"}\n{"role":"assistant","content":"ok"}\n';
const r=e.select(e.parse(raw),{e001:'pinned'},9999);
assert.ok(r.packet.includes('`````jsonl'));assert.ok(r.packet.includes(raw));assert.equal(r.manifest.packetBytes,Buffer.byteLength(r.packet));
});
test('selection is deterministic and leaves inputs intact',()=>{
const before=JSON.stringify(exchanges), priorities={e003:'aside'};
assert.deepEqual(e.select(exchanges,priorities,1000),e.select(exchanges,priorities,1000));assert.equal(JSON.stringify(exchanges),before);assert.deepEqual(priorities,{e003:'aside'});
});
+52
View File
@@ -0,0 +1,52 @@
"""Check the existing signup service in isolation; never writes production data.
Usage: python3 tests/signup.py /path/to/existing/server.py
"""
import importlib.util
import json
import sys
import tempfile
import threading
import urllib.parse
import urllib.request
from http.server import ThreadingHTTPServer
from pathlib import Path
spec = importlib.util.spec_from_file_location('signup_under_test', sys.argv[1])
server = importlib.util.module_from_spec(spec)
spec.loader.exec_module(server)
class NoRedirect(urllib.request.HTTPRedirectHandler):
def redirect_request(self, req, fp, code, msg, headers, newurl):
return None
with tempfile.TemporaryDirectory(prefix='priority-signup-') as directory:
root = Path(directory)
server.DATA = root / 'signups.jsonl'
server.SITES = root / 'sites'
(server.SITES / 'context-priority').mkdir(parents=True)
(server.SITES / 'context-priority/index.html').write_text('isolated published-page fixture')
httpd = ThreadingHTTPServer(('127.0.0.1', 0), server.Handler)
thread = threading.Thread(target=httpd.serve_forever, daemon=True)
thread.start()
url = f'http://127.0.0.1:{httpd.server_port}/api/signup'
opener = urllib.request.build_opener(NoRedirect)
def post(fields):
request = urllib.request.Request(url, data=urllib.parse.urlencode(fields).encode(), headers={'Content-Type': 'application/x-www-form-urlencoded'})
try:
return opener.open(request)
except urllib.error.HTTPError as response:
return response
fields = {'venture':'context-priority','email':'test@example.invalid','plan':'workshop','note':'isolated acceptance','website':''}
response = post(fields)
assert response.code == 303
assert response.headers['Location'] == '/v/context-priority/?joined=1#join'
row = json.loads(server.DATA.read_text())
assert all(row[key] == fields[key] for key in ['venture','email','plan','note'])
before = server.DATA.read_text()
assert post({**fields,'email':'invalid'}).code == 400
assert post({**fields,'website':'bot'}).code == 303
assert server.DATA.read_text() == before
assert post({**fields,'venture':'unpublished'}).code == 404
httpd.shutdown()
httpd.server_close()
print('PASS: real handler, isolated form POST, 303 redirect, record, invalid email, honeypot and unpublished venture guard. No production data written.')