Skip to content
NithishaVenkateshPublic

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Repository files navigation

Resident

Hold a whole repository in one model context, by asking a compressor what your task does not need.

License Tests Built with Paritok

Built with Paritok — the compression model this project uses as a relevance oracle.


The one idea

Post a segment of source to Paritok's hosted /compress endpoint together with a query. If the model judges the segment irrelevant to that query, it answers HTTP 200 with an empty body.

Every implementation we have read treats that empty body as an error and falls back to sending the original. Paritok's own shipped GpuServerStrategy.compress() returns str, and returns the caller's own content on 401, on 403, on any exception, on gpu_available: false, and on a non-string body. There is no status channel, so "irrelevant" and "the backend died" are the same value.

Read the other way, an empty body is not a failure. It is a verdict worth zero tokens.

response the common reading Resident's reading
empty body, provably complete "nothing to compress" → send original Drop — 0 tokens
non-empty body keep Keep(body, ref_id)
body identical to input keep Degraded(passthrough)
unbalanced [SEG introduced keep Degraded(malformed)

That distinction is the entire project. A compressor returning $r \approx 0.26$ on kept content still costs a quarter of a repository. A compressor that can also return 0 for content the task does not need makes cost scale with relevance to the current intent rather than with repository size.

Everything else in this codebase exists to make that difference measurable and safe, which turned out to be about 95% of the work.


Install

uv tool install git+https://github.com/NithishaVenkatesh/Paritok      # recommended
pipx install git+https://github.com/NithishaVenkatesh/Paritok         # or
git clone https://github.com/NithishaVenkatesh/Paritok && cd Paritok && pip install -e .

Python 3.11+. A free Paritok key comes from paritok.com.

The base install is 18 MB. To reproduce the published fidelity figures exactly, add the eval extra:

pip install -e ".[eval]"

That extra pulls paritok-audit, the extractor every published fidelity number was measured with — and, transitively, paritok[proxy] → sentence-transformers → torch, which takes the environment from 18 MB to 767 MB. None of it is ever imported: paritok_audit.atoms was traced at runtime and reaches only ast, re and dataclasses. Without the extra the ledger falls back to core/facts_alt.py, the independently written extractor, and every context pack states in its header which one built it.

resident init

init takes the key, then proves the backend is actually filtering before you trust a single number from it — see doctor for why that is not a formality. Only a key the canary has just validated is written to disk (~/.config/resident/key, mode 0600); resident init --forget removes it, and PARITOK_API_KEY in the environment always wins over the stored copy.

Shell completion, if you want it: resident --install-completion.


Quickstart — use it with the coding agent you already have

Resident is not tied to any one agent. scan --out writes a context pack: the whole repository, admitted under your intent, as one file you hand to Claude Code, Cursor, Copilot, an SDK loop, or a chat window.

resident scan . -i "where do we retry a failed operation after waiting?" -o residency.md

scan prints a verdict breakdown and the residency total, then writes the pack. Measured figures for one source under exactly that intent — joblib 1.5.3, cloned at its tag, from the corpus B run (eval/FULLRUN_RESULTS_B2.json):

segments tokens
source 281 216,123
dropped to zero 29 0
compressed 181 —
verbatim (below the compressor's floor) 71 —
residency 78,597 — 63.6% reduction
residency with the fact ledger on (the default) 104,906 — 51.5% reduction

The default carries the ledger, which trades ~12 points of reduction for atom retention of 97% against an independent extractor. --no-facts gives the first row.

Then, in whatever agent you use:

Read residency.md and enumerate every site that retries after a delay.

The pack self-describes. Its header tells the reading model what a [REF:...] entry is, what a tombstone means, and — critically — that an absent segment is a recorded decision, not an oversight. That is the one thing a downstream model cannot infer from the bodies alone.

Only resident ask needs an ANTHROPIC_API_KEY. Everything above needs PARITOK_API_KEY alone.


How it works

flowchart TB
    A["working tree"] --> B["segment.py — AST boundaries, 512 ≤ t ≤ 3000 tokens"]
    B --> C{"store.py — cache hit?"}
    C -- "miss" --> D["adapters/paritok.py — POST /compress with query"]
    D --> E["verdict.py — parse exactly once into Drop / Keep / Degraded"]
    C -- "hit" --> F
    E --> F["scan.py — assemble · facts.py — restore lost atoms"]
    F --> H{"fits the budget?"}
    H -- "yes" --> I["context pack via --out  ·  agent.py ask + pager"]
    H -- "no" --> J["REFUSE, exit 4 — never truncate"]

    style E fill:#8A2BE2,color:#fff
    style J fill:#c0392b,color:#fff
Loading

1. The verdict type came first

core/verdict.py is 79 lines and the highest-risk file in the system, because four very different events all arrive as a string:

""                        a genuine DROP
""                        a torn connection, truncated mid-body
<the original content>    the backend is down and passed content through
<half a [SEG] block>      the reply was truncated by num_predict

Collapsing those into str | None is exactly how you publish a 97% saving on a run where the compressor never executed. So the boundary parses once, into a closed set:

stateDiagram-v2
    [*] --> HTTP_200
    HTTP_200 --> EmptyBody: body is empty
    HTTP_200 --> NonEmptyBody: body is not empty

    EmptyBody --> Drop: completeness signal present
    EmptyBody --> Degraded_truncated: no completeness signal

    NonEmptyBody --> Degraded_passthrough: body equals input
    NonEmptyBody --> Degraded_malformed: SEG imbalance introduced
    NonEmptyBody --> Keep: otherwise

    Drop --> [*]: 0 tokens
    Keep --> [*]: compressed body plus ref_id
    Degraded_truncated --> [*]: coverage hole, exit 3
    Degraded_passthrough --> [*]: coverage hole, exit 3
    Degraded_malformed --> [*]: coverage hole, exit 3
Loading

Two rules in the adapter follow from this and are not optional:

  • An empty body alone is never sufficient for a Drop. It must carry a positive completeness signal — Content-Length: 0, or a cleanly terminated chunked stream. This makes a transport failure structurally incapable of manufacturing a drop. Without it, some fraction of any measured false-drop rate is a network fault wearing a verdict's clothes.
  • Never call _unwrap_seg. Paritok's local_model._unwrap_seg returns the whole stripped reply when the [SEG]…[/SEG] wrapper is unbalanced — which is precisely what a num_predict-truncated generation looks like. Routed through it, a truncated reply becomes a plausible non-empty body.

is_usable() gates every savings calculation, and a run containing any Degraded verdict exits 3 and reports no saving at all.

The adapter subclasses GpuServerStrategy and overrides exactly one method, so __init__, check(), _base() and GpuServerConfig are all inherited. The subclass is simultaneously the fix and the bug report.

2. Segmentation

core/segment.py splits on ast boundaries with a line-window fallback, bounded by $512 \le t \le 3000$ tokens.

  • The floor is Paritok's own min_tokens gate (config.py:54). Sub-floor content comes back uncompressed and would read as a Keep.
  • The ceiling is the shipped runtime's CHUNK_SIZE = 3000, even though the training and benchmark value in the same file is 2000 and a docstring warns that beyond ~2000 tokens the model leaves its trained distribution. That warning was treated as a hypothesis to measure, not a fact to obey: at $N \approx 302$ segments and 9–20s per keep, halving segment size costs 57% more calls on a throughput-bound system. Gate A5 measured verdict stability at both and the cap stayed at 3000.

Ordering is deterministic and independent of completion order — otherwise concurrency reorders the prompt prefix and every upstream cache hit vanishes. Small files batch only within a package, never across intent-named paths. Symlink containment is an explicit check, not a reliance on CPython rglob behaviour.

3. The residency store

core/store.py is content-addressed, and the key carries everything that affects the output:

$$k = H(\text{schema},\ \text{paritok_version},\ \text{endpoint},\ \text{kind},\ \text{upstream_model},\ \text{sha256(content)},\ \text{intent_bucket})$$

Paritok's own cache is keyed on content alone (compress.py:210), so the same bytes return the same compression regardless of the intent they were compressed for — quietly defeating the strongest lever the model has. Two further rules were each learned from a specific failure:

  • Drop is a stored value, never key absence. An empty body is falsy, so the natural if result: cache.set(...) persists no drops at all — and drops are the majority case. Negative TTL equals positive TTL.
  • Never consult a path→id map. Paritok's does substring matching (compress.py:186-188), so deleting a trailing function makes the new file a substring of the old one and it serves the pre-edit compression. Reproduced, not inferred.

TTL is 7 days with ±10% jitter, because 300 keys written in one scan with identical TTLs all expire within the same few minutes and turn the next run into a fully cold hour.

4. Admission and assembly

flowchart TB
    V{"verdict"} --> K["Keep"]
    V --> D["Drop"]
    V --> G["Degraded"]

    K --> KF{"atoms lost<br/>vs original?"}
    KF -- yes --> KL["body + '# facts:' line<br/>(literal substrings)"]
    KF -- no --> KB["body"]

    D --> DA{"segment<br/>carries atoms?"}
    DA -- yes --> DT["'# dropped, facts:' tombstone<br/>+ ref id → reversible"]
    DA -- no --> DZ["nothing<br/>true 0-token drop"]

    G --> GH["declared coverage hole<br/>never treated as a drop"]

    style DZ fill:#27ae60,color:#fff
    style GH fill:#c0392b,color:#fff
Loading

core/scan.py runs bounded concurrency with a polite AIMD ramp, granular connect/read/total timeouts, exponential backoff with full jitter, and capped attempts. Every verdict is written to the store as it lands, so Ctrl-C costs at most the in-flight batch.

If the assembled residency does not fit the budget, it refuses rather than truncates — a truncated residency is top-$k$ retrieval wearing a coverage claim.

5. The fact ledger

Corpus B produced the number that changed the design. Across 2,150,959 tokens the corpus holds 86,877 critical atoms by the scorer's extractor and 87,516 by the independent one (paths, identifiers, error classes, numbers, commands, URLs, hashes), and

$$\bar{t}_{\text{atom}} \approx 4.75\ \text{tokens}$$

while losing one atom costs a full fidelity point. Atoms are cheap in tokens and expensive in fidelity. The fact-gated family of strategies gets the contract right — exact facts must survive verbatim — but the usual remedy is wrong by an order of magnitude: when facts die it restores the entire original segment, which is why that arm sits at ~27% reduction.

core/facts.py restores only the missing facts. Both the # facts: line and the # dropped, facts: tombstone are literal substrings of the source, so retention stays decidable by exact search.

Measured effect: independent-extractor fidelity 54% → 97% for about 8 points of reduction. The ref pointer that makes tombstones reversible costs 0.09 points (52.28% → 52.19%) — a cheap price for a whole-segment recovery path.

6. Paging, owned rather than delegated

core/agent.py never uses Paritok's expand_context virtual tool. Measured against the proxy: it answers an expansion by re-POSTing the whole thread with the original attached, so for compression ratio $c$ an expanding turn costs

$$C_{\text{expand}} = T(1 + 2c) > T$$

— worse than never compressing. That loss lives in the gateway's control flow, not in compression, so owning the paging avoids it by construction.

sequenceDiagram
    participant M as model
    participant P as Pager
    participant R as residency (byte-stable prefix)

    M->>R: turn 1, reads compressed entries
    M->>P: expand a ref id
    P->>P: pin the original at turn 1
    P-->>M: appended at the END, prefix untouched
    Note over R,P: prefix stays byte-stable,<br/>so upstream caching still hits
    M->>M: turns 2 to 8
    P->>P: evict at turn 9, unpin_after = 8
    Note over P: the pager IS a pinning mechanism.<br/>Without eviction the residency<br/>inflates monotonically.
Loading

Residency content is treated as untrusted: Paritok's rules preserve error strings verbatim, so text placed in a source file reaches the model. The residency is wrapped in a nonce-delimited envelope, the system prompt marks it as data, and the tool surface is read-only — no shell, no writes.

7. Measurement infrastructure

core/ledger.py is an append-only log; eval/recompute.py regenerates every published number from it. Nothing in the reports is typed by hand. The evaluation protocol was committed before any arm ran, with pre-registered falsification thresholds.

One accounting rule earns its own note. Anthropic splits prompt tokens across three fields:

prompt = input_tokens + cache_creation_input_tokens + cache_read_input_tokens

A system whose whole design is a large stable cached prefix would omit almost all of its own cost by reading only input_tokens — producing a spectacular and completely false saving, in the flattering direction.


CLI reference

resident init

First-run setup. Takes a key, issues the canary probe, and refuses to continue unless the backend genuinely drops it.

flag default meaning
--save/--no-save save store the validated key at ~/.config/resident/key, mode 0600
--forget — delete the stored key and exit

The key is written only after the canary passes, so a bad key is never left on disk for later commands to trip over, and PARITOK_API_KEY always takes precedence over the file.

resident doctor

Checks the backend is compressing, not merely reachable.

It deliberately ignores Paritok's /test, which has been measured reporting the GPU online while /compress returned gpu_available: false and passed content straight through. Instead it POSTs a fixed canary — an ASCII-banner helper — under a mismatched refund intent. That pair returned empty 20/20 during Gate A, so a non-empty reply means relevance filtering is not working, whatever /test claims.

resident scan

resident scan <path> -i "<intent>" [-o residency.md]
flag default meaning
--intent, -i required what you are working on; the admission query
--out, -o — write the context pack here; - for stdout
--budget 160000 residency token budget; over it, refuse (exit 4)
--concurrency 3 parallel compression requests
--dry-run off estimate cost and wall clock, send nothing
--redact off mask detected secrets instead of refusing
--guard off conservative prefilter — see below
--facts/--no-facts on fact ledger and tombstones
--without-paritok off removal test: the same pipeline, no oracle
--live/--no-live on live residency monitor

Secrets are gated by default. scan egresses a working tree to a third party, so it refuses outright when it finds anything secret-shaped and requires explicit --redact to proceed.

--guard is off, and that is a published negative result. The conservative prefilter was the architectural centrepiece of the original design — the argument that coverage was architectural rather than statistical. Two corpora said it changes recall not at all and costs 304,651 extra tokens on a 1.43M-token corpus, because force-kept segments are sent verbatim. It survives as an opt-in flag.

--without-paritok reports honestly. With the oracle removed nothing is dropped or compressed, and the pack costs more than the source, because every entry still carries a [REF:…] header. A removal test that showed a saving would be measuring something other than Paritok.

resident ask

resident ask <path> "<question>"      # also needs ANTHROPIC_API_KEY

Makes the repository resident, then runs the enumeration loop with the expand tool over the pager. This is the only command that talks to a model provider.

resident bench

Runs the pre-committed local baselines (uncompressed, ripgrep, prefilter-only, and optionally ripgrep with answer-key patterns) and writes a results file. No Paritok calls.

Exit codes

code meaning
0 ok
1 error
2 usage — reserved, so a bad flag is never confused with a degraded run
3 degraded — completed, but the numbers are not trustworthy
4 refused — would not fit; refused rather than truncated
130 interrupted; completed verdicts are cached, re-run to resume

A degraded run exiting 0 is how a silent passthrough becomes a published "97% saving". It exits 3, and savings are not printed at all.


What was measured

Gate A — verify the premise before building on it

Nothing was built until the behaviour was confirmed on the hosted backend rather than local q4 weights.

# assertion result
A1 drop verdict responds to intent pass — 20 reps/cell, 80/80 calls, 0 errors
A2 a drop is recorded as billed dashboard activity pass
A3 content and key attribution pass
A4 explicit kind honoured pass, 3/3 distinct outputs
A5 verdict stable at 2000 vs 3000 tokens pass, cap kept at 3000
A6 concurrency and throughput 0.98 req/s at concurrency 3, 0/80 errors
A7 truncation leaks SEG markers not reproducible, check retained

A1 crossed two documents with two intents, 20 repetitions per cell:

document matching intent non-matching intent
refund.py 0/20 dropped 20/20 dropped
banner.py 20/20 dropped 0/20 dropped

A1 was pre-registered with four branches, not three — including a "stochastic proceed" branch for a 40–90% empty-body rate. Specifying repetitions at all concedes that variance is expected, so leaving the partial-agreement cell without a rule would have been an invitation to rationalise afterwards. The observed behaviour landed in the deterministic branch.

A2 mattered because the claim is that a drop is a real, billed, attributable unit of work. Baseline was read twice, 45 seconds apart, to confirm the reporting backlog had drained; then 100 verified drops were issued and predictions recorded before re-reading:

metric baseline predicted observed
requests 822 922 922
tokens processed 811,600 840,700 840,700
tokens saved 539,400 568,500 568,500
ratio 0.335 0.324 0.324

The alternative hypothesis — drops counted as requests but not as savings — predicted 0.358. A drop is credited as a 100% saving, exact to the token.

The corpora

Corpus A — 12 sources, 1,289 segments, 1,430,065 tokens. Five Python libraries as installed packages at pinned versions (filelock 3.32.2, fsspec 2026.7.0, httpcore 1.0.9, joblib 1.5.3, playwright 1.62.0), plus seven further third-party repositories.

The library part is what pip install puts on disk, not what git clone does. That is deliberate: an agent in a real environment reads site-packages continuously and upstream repositories rarely. It is stated because a reduction figure is only meaningful against a named denominator — and then verified: each library was cloned at the tag matching its installed version and compared by content hash, and 245 of 248 .py files are byte-identical. The three exceptions are version.py, _version.py and _repo_version.py, generated at build time.

Corpus B — the same 12 sources with the five libraries swapped for full clones at those tags. 2,275 segments, 2,150,959 tokens: a factor of 1.72 on the library part and 1.50 overall. The added content is tests, benchmarks, examples and documentation config, and it grows unevenly (filelock 3.15×, joblib 1.11×), so per-source results were expected to move by different amounts and possibly in different directions.

Per-source detail is published for the five named libraries. The other seven are reported as third-party-01…07; they are other people's repositories and are not ours to republish.

Metrics

Reduction is measured over every token in the corpus, including sub-floor content sent verbatim:

$$R = 1 - \frac{\sum_i T^{(i)}_{\text{out}}}{\sum_i T^{(i)}_{\text{in}}}$$

Fidelity is atom retention by exact substring search, the same rule paritok-audit scores by:

$$F = \frac{\sum_i |{a \in A(x_i)\ :\ a \subseteq y_i}|}{\sum_i |A(x_i)|}$$

Every fidelity figure is computed twice — once with paritok-audit's extractor, once with an independently written regex set (core/facts_alt.py) using a different category scheme. If the system were memorising one extractor's quirks, it would fail on the other.

Recall intervals are Wilson, not Wald. The normal approximation collapses to zero width at $\hat{p} = 1.0$ — exactly the regime a coverage system reports in — and would claim literal certainty from 40 out of 40.


Results

Recall on real code — corpus A, 20 ground-truth sites

Ground truth is generated by a structural rule over the AST: a function is a site if it carries a retry decorator, or if a single enclosing loop contains both an except handler and a sleep call.

arm recall 95% CI (Wilson)
ripgrep, human-written pattern 13/20 — 65.0% 43.3 – 81.9
ripgrep, patterns derived from the answer key 19/20 — 95.0% 76.4 – 99.1
Resident 18/20 — 90.0% 69.9 – 97.2

At $N = 20$ the intervals overlap and the arms are not statistically separable. Resident beat the human-written pattern and won two repositories where that pattern scored 0/1; a pattern derived from the answer key beat Resident. That is the honest summary and it is stated that way in the report.

Head to head — corpus B, 8 arms, 3 repetitions, 2,150,959 tokens, 271 minutes

Five of the eight arms ask Paritok the same question and differ only in how they treat the answer, so cost is $3N$ per repetition rather than $8N$.

arm reduction fidelity (scorer) fidelity (independent)
stock 49.4% ± 0.1% 62.7% ± 0.1% 64.6% ± 0.1%
resident 60.6% ± 0.1% 52.8% ± 0.1% 54.5% ± 0.1%
per-segment intent 53.7% ± 0.4% 61.0% ± 0.4% 63.2% ± 0.4%
fact-gated 26.6% ± 0.2% 78.2% ± 0.1% 79.2% ± 0.2%
resident + tombstones 58.9% ± 0.1% 62.7% ± 0.1% 63.8% ± 0.1%
resident + fact ledger 52.3% ± 0.1% 100.0% 97.3%
stock + ledger (ablation) 42.8% ± 0.1% 100.0% 98.2% ± 0.1%
per-segment intent + ledger (ablation) 46.6% ± 0.4% 100.0% 98.0% ± 0.4%

Spread is $(\max - \min)/2$ across the three repetitions. Run-to-run spread is 0.1–0.4 points while the gaps between arms are 3–10 points, so the ordering survives the noise. On corpus A the same four core arms ordered identically (resident 60.7% ± 0.2%, per-segment intent 57.3% ± 0.2%, stock 51.0% ± 0.6%, fact-gated 22.8% ± 0.5%).

No arm is beaten on both axes. That is the correct reading of the table, and the reason both axes are always reported together.

The ablation that had to be run

stock + ledger and per-segment intent + ledger exist to answer the obvious objection: is the fact ledger a Resident advantage, or a universal post-processor?

The answer is universal. All three ledgered arms reach ~100% on the scorer and ~98% on the independent extractor. Resident's real advantage is narrower and should be stated as such: because Resident drops more segments, the same ledger costs it fewer tokens — 52.3% reduction against 42.8% and 46.6%.

The metric that is circular, said out loud

100% scorer fidelity is circular by construction. The ledger is built from the scorer's own extractor, so of course the scorer finds everything. It is reported as a sanity check only. The defensible numbers are the independent extractor's results and the task-level evaluation below.

Task-level evaluation: presence is not usability

eval/task_eval.py generates answerable questions from each segment and applies three checks — exact (the answer string appears), context (it appears within 200 characters of the symbol it belongs to), and relationship (a pair such as raise ConfigError has both parts present, near each other).

The result is uncomfortable and worth publishing: exact rates reach 100%, while context rates sit at 3–6% and relationship rates at 6–10% across every arm, ledgered or not. The ledger reinjects atoms as a flat list, so the string survives but its association with its function or its exception handler is often lost.

Atom retention — the standard fidelity metric in this space — measures presence, not usability.

Two follow-up variants were built and measured against that finding:

variant reduction independent fidelity context relationship
flat ledger (shipped) 52.6% 97.2% 5.8% 8.4%
grouped by enclosing def/class + verbatim pairs 49.3% 97.8% 5.9% 11.9%

Grouping atoms under their enclosing symbol cost 2.31 points of reduction and moved the context rate from 5.8% to 5.9%, so it was built, measured and removed. Re-emitting broken pairs as verbatim snippets did work (8.4% → 11.9% for 0.73 points) and is documented in-source as the strongest candidate if that axis ever outranks size. Both results live in the code comments so the next person does not rebuild them.


Limitations

Stated because a results section without one is not a results section.

  • Recall is measured at $N = 20$ on real code, and the intervals overlap. The answer key comes from a structural rule over corpus A and does not transfer to a different file set.
  • The agent loop has not been exercised at corpus scale. core/agent.py, the pager and the eviction policy are implemented and unit-tested against mocked transport; the published benchmark measured the substrate — segmentation, admission, assembly, fidelity — and never involved a model provider.
  • The fact ledger cannot restore single-word literals. Tested directly against core/verdict.py: the extractor captures gpu_unavailable and invalid_key (snake_case matches its identifier pattern) but not passthrough, timeout, malformed, refused or truncated. Those are not atoms under any of its rules, so no ledger can put them back, however lossy the compression was. A reader of a pack can therefore lose three of the five DegradedReason values with no marker saying anything is missing — unlike a drop, which at least leaves a tombstone. This is the concrete mechanism behind the low context and relationship rates above, and it is a property of the extractor rather than of the compressor.
  • Comparison arms are reimplementations of each published strategy from its description, not the authors' code. The fact-gated arm's level ladder depends on the level parameter, which is a confirmed no-op on the hosted backend, so that arm implements only its final fallback.
  • 30 of 1,289 corpus A segments returned Degraded across 8 of 12 sources. Runs containing a Degraded verdict exit 3 and report no saving.
  • cl100k is used for sizing only. Billing figures come from provider-reported usage.
  • 100% scorer fidelity is circular, as described above.

Known substrate behaviour, and what went back upstream

Found by using Paritok properly, each one reproduced, and where it was ours to fix, fixed:

defect status
result cache keyed on content alone, so intent and level are ignored on repeat PR #26 — ours, open
path short-circuit returns stale compression after a trailing function is deleted PR #26 — a regression the first cache fix introduced
a single line larger than CHUNK_SIZE fails with HTTP 400 PR #25 — ours, open
/test reports GPU online while /compress returns gpu_available: false and passes content through reproduced 5× over 35 min; already filed by another contributor
level accepted and ignored on hosted confirmed by the maintainer, issue #3
Python-urllib User-Agent rejected with HTTP 403, indistinguishable from a rejected key measured

PR #26 is worth a note: it builds on someone else's cache-key fix, keeps their commit and credits them, and adds the repair for a regression that fix introduced — results were stored under the new wide key but still read through the old narrow one.

The largest finding is not in that table because it is a design issue rather than a defect: compress() returns str for four distinct outcomes, so no caller can separate “irrelevant to your query” from “the backend died.” That is the root cause of issue #20, where an empty body is accepted as a summary and silently destroys a tool result. The fix proposed there would repair the data loss but collapse the verdict into the failure case; the typed-outcome version in this repository's adapter keeps both distinguishable, and the completeness requirement makes a torn stream structurally incapable of presenting as a verdict.

paritok is pinned at exactly 1.2.8, not >=, because 1.2.9 is announced to change /stats semantics such that re-delivered originals fold onto the compressed side and savings can go negative. A silent minor upgrade would change the substrate underneath a published benchmark.


Reproduction

pip install -e .
export PARITOK_API_KEY=pk_live_...

resident doctor
resident scan <path> -i "where do we retry a failed operation after waiting?" -o residency.md

# full head to head: 12 sources x 8 arms x 3 repetitions
RESIDENT_TASK_EVAL_SAMPLE_RATE=0.13 \
RESIDENT_CORPUS=eval/selected_repos_B.json \
RESIDENT_CHECKPOINT=eval/fullrun_checkpoint_B2.json \
RESIDENT_RESULTS=eval/FULLRUN_RESULTS_B2.json \
python -m resident.eval.fullrun 3

# task-level evaluation, offline
python -m resident.eval.task_eval eval/fullrun_checkpoint_B2.json

# every published number, regenerated from the append-only log
python -m resident.eval.recompute eval/events.jsonl

eval/anonymize.py is committed so the one transformation applied to published artifacts is auditable: third-party source identities are replaced with opaque ids. It renames keys only — no measured value is read, computed or altered.


Project shape

34 modules, 5,459 lines of source, 143 tests across 11 files. CI runs four gates on every push — ruff check, ruff format --check, mypy --strict over the whole package, and the test suite — and never contacts the Paritok endpoint: every network interaction in the tests is a fake or a recorded fixture, because the endpoint is slow, non-deterministic, and unavailable to forks.


Licence

Apache 2.0 — see LICENSE and NOTICE.

Built with Paritok.

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages