Repository navigation
Releases: nurmdrafi/pi-native
Releases · nurmdrafi/pi-native
Release list
v1.70.0
What's Changed
Added
- Subagent control verbs.
subagent_controlstops, cancels, and re-dispatches live children by
name; cancel finalizes through the standard delivery funnel so exactly one result lands and the
scope lock releases. - Stalled-child recovery and atomic panes. Stalled children are detected and recovered; panes
launch atomically, dead multiplexers heal, completion signals travel over a wait-for channel with
an exit sidecar. - Queueing past the cap. Spawns beyond the concurrency cap queue without blocking the turn.
- Declared file-scope locks. A spawn's declared
files:scope queues conflicting spawns FIFO
behind the owner; read-only and unscoped spawns never queue; locks release at result delivery and
survive pane-loss restart. - Result records and prior-work injection. Results carry
files_changedfrom a spawn-time git
baseline; append-only subagent history (rotated to the last 500 lines) survives result-inbox
drain; a scope overlapping recent history injects capped prior-work context into the task. - Live metrics and baselines. Per-child live metrics with p90 history baselines and
duplicate-spawn warnings; dashboard subagent health cards, deep links, and a drill-in session
modal; a wave-metrics extractor script; the dashboard UI is built in bootstrap and after-pull. - Fail-closed gate for children. Destructive confirms fail closed inside subagents (no dialog
can be answered there), and the permission gate is re-enabled in every sandboxed child. - Roster at 14 specialists. Six new profiles — architecture review, security review, frontend,
Rust, product briefs, session audit; fixer absorbed into worker; every profile hardened against
logged failure modes. - Issue-orchestrator facts-file handoff. One facts file per issue group, written once; workers
re-read only the files it names; routing splits Rust, browser-UI, and general work onto matching
agents.
Changed
- Doctrine lives in
docs/subagents.md. Orchestration rules moved out ofAGENTS.md; the
roster table plusagents/frontmatter are the sync surface;AGENTS.mdkeeps only the opt-in
gate and a pointer, shrinking every session's always-on context. - Faster delivery paths. Single-parse result delivery, deduped session reads with cached agent
discovery, byte-offset budget reads. - Docs ground the workflow. README subagent-orchestration section; scope locks, control verbs,
and executor doctrine documented; token-aware delegation gate enforced in the agents docs;
prompts forbid touching the default branch. - Default thinking level lowered to high; repo-local
.pi/runtime state ignored.
Fixed
- Subagent state isolated per project. History and inbox no longer leak across projects; stale
inbox records reach unrelated sessions as context-only. - Delivery hardening. Watcher aborts mid-poll settled; multiplexer stderr kept out of failure
wraps; history crash residue tolerated on append; suite type errors repaired; test suites
isolated from the real durable inbox. pireadnull handling. Call labels screen serialized null hits; explicit null accepted for
optional params.- Issue orchestrator correctness. Refined base sanity check and issue processing; merge order is
canonical everywhere — PR creation order, oldest first.
v1.69.0
What's Changed
Added
- Fused locate+read (
piread --hits). One call returns merged context windows around every
matching line plus pointers to hits past the budget: 72,445 B / 27 calls against the built-in
read's 399,683 B / 11 on the 27-task lookup corpus (0.18x the bytes). - Wider default read budget. A read now carries 100 lines / 8 KB before a gap marker (was
40 lines / 2 KB), so ordinary windows arrive whole and follow-up reads are rarer. - Read budget and locate bounds are generated, so the Rust tools, the gate and the docs read
the same numbers.
Changed
- Every native tool is Rust-only. pibash, piread, piedit and pidx register unconditionally and
never fall back to a built-in executor; a missing or broken binary is a tool error plus one
stderr line instead of a silent downgrade. - Built-in tools are a configuration choice.
PI_NATIVE_READ,PI_NATIVE_BASH,
PI_NATIVE_EDITandPI_NATIVE_PIDXare gone; use pi'sread/bash/editby leaving the
extension out or by setting the gate'snativeReadFirst/nativeBashFirstrules tooff. - Read coverage comes from structured windows. The gate certifies a fused read from
details.locate(printed windows, complement recorded as unread gaps) and seeds locate-first
anchors from the reported hit lines; the read ledger stores the same complement. - Images read as text. piread serves image and other binary files as lossy text like any other
content, and the built-in image route is gone; the tool no longer points at areadtool that
may not exist.
Fixed
npm run dashboardboots again. The server had lost its configuration block, so it died on
ReferenceErrorbefore listening; it now reads its sessions tree, pidx cache, gate config, poll
and active windows, honoursPI_DASH_PORT/PI_DASH_SESSIONS_DIR/PI_DASH_SESSION_BUDGET,
and logs the port it actually bound.doc:checkreports all four families clean. The checker now scansdashboard/scripts/, waives
git subcommand flags, and every documented environment key resolves.- Fused hit pointers and structured hits agree.
details.locate.hitscarries the printed hits
plus the footer pointers, so locate-first anchoring no longer misses lines the footer named.
v1.67.0
What's Changed
Added
- Subagent budgets. Every subagent now runs under finite ceilings — wall-clock seconds, assistant
turns, cumulative USD cost — with a clean stop and abudget_exceededresult when breached.
Ceilings resolve from agentbudget:frontmatter,budgetDefaultsconfig, or builtin defaults;
spawn-time overrides may only lower them. - Budget persistence on resume. A resumed subagent inherits its spawn-time budget: the wall
clock restarts while turns and cost re-meter from the preserved session file.
v1.66.0
What's Changed
Added
- Self-learn lessons store and skill routing. Verified lessons route to the home that owns
them: an existing skill whose domain covers the topic is updated through skill-manager, while
ownerless topics land inskills/self-learn/references/lessons/— one file per topic in a
trigger, mistake-shape, fix-code-block, evidence format that rejects prose-only entries. - Deployed code shapes in map-integration.
references/realtime-plotting.mdgains the
live-trace dashboard shapes behind its rules: the session-configured MQTT connection hook
(latest-ref callbacks, topic-set-keyed reconnects, bounded credential re-auth), the interval
batch buffer with its flush gate, the per-entitybatch_updatestore merge, the deck.gl
overlay viauseControl, and style-gated throttled viewport reads.
Changed
- Anchor Guard names every uncertified edit span. A multi-edit batch that misses
certification reports each failingedits[i]with its target line range and the exact
pireadcall that certifies it, replacing one opaque failure; the case corpus pins the
message format. - Read/edit prerequisites restated. SYSTEM.md scopes anchors to the current turn, requires
a search to name first-time paths (script-created files included) beforepiread, demands a
region re-read after half-failed batches or earlier-turn changes, pastes printed lines
verbatim into retries, resumes stopped reads at the named offset, and adds a context-budget
rule (~150K tokens) that prefers compaction over continuing. AGENTS.md drops the stale
commitlint filename, marks probe tests skippable for bug fixes, and directs config-file reads
to locate the basename instead of guessing its extension.
v1.65.0
What's Changed
Added
pidx --report lifecycle [--session ID]. A per-turn ledger — input, cache-read,
output, calls, result bytes — alongside four cross-turn waste detectors:dupCall,
resendAfterBlock(a duplicate edit whose earlier attempt was blocked),probeRepeat
(one target, three turns) andproseOnly(an output-heavy tool-free turn). Waste is
priced against the session's mean prefix, and the model is printed with the numbers so
an estimate is never read as an attribution. The detector core is pure, so the case
corpus pins the model without a session directory.- SS4 search rule.
rg -r/--replaceis display substitution, not recursion —
rgrecurses by default, so the flag silently changes what the command reports. Warned
under the newsearchReplaceFlagkey.
Changed
- One read budget.
SYSTEM.mddrops the 500-line window, the ~10 KB whole-file
bypass and the ~100-line tier for a single rule: one window is one unit inside the
~40-line / 2 KB model-visible budget, a larger unit is two deliberate windows, and
several units are several calls in one parallel block. - Anchor blocks carry their remedy. A not-found anchor returns the closest region as
paste-readyoldTexton the fragment path, or a bounded window (15 lines / 1.5 KB) plus
apiread {path, offset, limit}call when no fragment matches — so a block costs no
remedy round instead of a read plus a full payload re-send. --maxno longer hides the live session.select_sessionsfolds a dropped session
inside the live window back into the slice.- Post-block discipline in
SYSTEM.md: a block concerns one span, so only that region
is re-sent.
v1.64.0
What's Changed
Added
skills/self-learnand bash-env nvm loading.scripts/env.shis aBASH_ENVtarget that
loads nvm once for daemon-spawned non-interactive shells (shells whose node already resolves
skip the ~200 ms source), pinned bytests/unit/pibash-env.test.mjs;settings.jsonre-enables
pidx.- Warn-rule corpus cases.
errorSwallow,readerBypassandviewCreditjoin the gate case
corpus, with matching updates to anchor-guard, bash-cap, read-coverage and search-guard, the
case harness, region tests and the plan doc.
Changed
- Rule severities have one home:
extensions/permission-gate/config.json.config.tsis
renamedloader.tsand keeps only mechanics — the rule-key registry, severity coercion, env
overrides and the hard-rule floor — while theWARN_BY_DEFAULT/OFF_BY_DEFAULTshadow tables
are deleted. A key the file omits or garbles now fails closed toerrorwith a stderr warning
instead of consulting a code table; shipped behavior is unchanged because the tracked file lists
every key. The_commentdocuments theoff/warn/errorvocabulary,PGATE_<KEY>one-off
overrides and thedestructiveConfirm/commitMessageLintfloor. Measured: gate-config 28/28,
full check 249/249; loader 300 → 269 lines.
v1.63.0
What's Changed
Added
pidx --report usageandCONTRIBUTING.md— the usage report answers per-model
spend, cost tail and prefix trend from pidx's own extract cache (1.73 s → 0.19 s), and
skills/harness-engineer/scripts/usage-metrics.pyis deleted; its last job was walking
110 MB of session JSONL to derive what the cache already holds.CONTRIBUTING.mdstates
time-to-first-PR, the daily loop, conventions and where things live.TurnState(extensions/permission-gate/rules/turn-state.ts). The temporal rules (R10, EB,
LG1, R11, PH1, CN) shared thirteenlet/Mapbindings scattered through the extension factory,
withmutationSeqdeclared below the helper that read it. They now share one value and every
transition is a function of it.index.ts1570 → 1501 lines, block reasons unchanged.pidxclassifies gate blocks.results[].blkcarries the block family (anchor,tokens,
loop, …), matched only at the start of the result text so a session reading the gate's own
source is not counted as blocked. Extract schemav:2; the cache store version moves to 3 so
stale caches rebuild.tests/tools/audit/gate-metrics.mjs— repeats, failure-streak calls, blocks by family and
gate token share, computed from apidxextract instead of one-off scripts.tests/gate/region-warn.test.mjs— pins the AG2 severity contract:warnpasses, while a
never-read path and a byte-mismatched anchor still block.- Tooling rule in
AGENTS.mdandSYSTEM.md: reuse an existing native tool before writing a
script, plus the bar a new compiled tool has to clear. rust-skills: four compiler-optimization rules from the "Achieving warp speed with Rust"
guide —opt-flat-storage,opt-registers,opt-loop-unroll,opt-ilp— plus
assert-hoisting guidance inopt-bounds-checkand runtime-share guidance in
perf-profile-first. 265 → 269 rules.npm run audit:sessionandnpm run audit:bin-diff— two reusable audit drivers.
session-blocks.mjsparses a session JSONL directly and reports chaining, the block ledger with
gate families and recovery, and re-derives the piread compaction contract from recorded results;
it caught the compaction drift on real session data.bin-diff.mjsis the byte-for-byte
differential between two builds of one native tool — shape corpus × argument grid plus a--serve
stream mode, exit 1 on any difference; it gated the piread scanner refactor.npm run bench:piread,bench:pibashandbench:piedit— all three micro-benches already existed in
tests/tools/bench/with no entry point and the same stale../../extensionsimport, so none had
run in weeks. All are wired, repaired and listed intests/README.md.
Changed
- piread scans without per-line reads.
Segmentersearches each fill buffer withmemchr
instead of callingread_untilper line, andread_textstops decoding and buffering selected
lines once the head buffer is saturated — they can never be rendered, and the only state those
calls still moved was a counter nothing reads after the scan. Output is byte-identical (128
corpus × argument cases, CLI and daemon); a 250k-line / 5.7 MB read goes from 15.7 ms to 7.9 ms
median, while a 2,500-line read is unchanged. pieditborrows its fuzzy view.normalizeForFuzzyMatchran NFKC over the whole file because
duplicate counting needs the view even for an exact edit. The view is now borrowed when the
transformation is provably the identity — ASCII content with no line ending in whitespace — and
theexpectthat assumed a materialized view became a fallback to the content itself. Worth
~0.5 ms on 589 KB (below bench noise), but it drops a full-content pass and a panic path from the
request handler.- AG2 (
editRegionGuard) honours its configured severity. Its block bypassedenforce, so
warnblocked exactly likeerror. Each anchor decision now carries the rule that owns it and
severity is applied per rule. The shipped default stayserror; plan §12 records the watch
criteria and flip procedure for relaxing it. config.jsondestructiveConfirmset toerror(the hard-rule clamp already forced it).custom-tools/workspace renamed torust-tools/. Docs, scripts, extensions and tests
updated;docs/custom-tools-architecture.md→docs/rust-tools-architecture.md; all five
binaries rebuilt and reinstalled from the new path.pre-push-reviewskill renamed tocode-reviewer(/skill:code-reviewer), with
company-specific context removed fromSKILL.mdand references.
Fixed
- Compaction tiles every window exactly.
compactcounted lines withsplit_lines, which
drops the body-final empty segment, so a trailing-blank window claimed one line fewer than it
rendered and head+gap+tail missed it. It now splits on'\n'and attributes each omission from
max(kept, rendered);renderedCoverageFromBlocks/renderedSpansFromBlockstake the read
window's end, so the backward anchor maps the final run onto it. Found by the cross-layer
differential (tests/parity/piread-compaction-walk.test.mjs: realbin/pireadoutput → TS walk),
locked by the 300-casereconstructs_the_window_exactlysweep and
trailing_empty_window_line_is_fully_accounted. - A user-configured AG2
warnhad no effect: the anchor guard returned its block directly instead
of through severity enforcement. pibashscanned each output chunk three times.OutputAccumulator::append_decoded_text
walked a chunk to record newline offsets, walked it again withmatches('\n').count(), then a
third time forrfind. The count now comes out of the first loop. Output is byte-identical
(15-filecatcorpus plusseq 50000, path/timing fields excluded), a 290 KB / 50k-line command
drops from 12.71 to 11.84 ms median (~7%), andseq 2500is unchanged. Every pibash benchmark
class is now below its built-in oracle, so the long-standingseq 50000acceptance note is
retired.skills/rust-skillsnever loaded. Its frontmatter had a quoted scalar followed by trailing
text (- "Achieving warp speed with Rust" (jFransham, gist)), which is invalid YAML, so the loader
dropped the whole skill: no/skill:rust-skillsentry and nothing injected on invocation. The
scalar is plain now, andtests/unit/skills-frontmatter.test.mjsfails on any loader diagnostic
or anyskills/*/SKILL.mddirectory that does not load.pidxno longer rewrites an up-to-date extract file. The indexer already skipped
rewriting its store when nothing changed, but still rewrote the extract file that is a pure
function of that store — 15 MB per warm call on this corpus. A warm run now leaves an
up-to-date file untouched (444 → 28 ms median, ~16x; full re-parse unchanged at ~2.1 s), the
output stays byte-identical, and a missing or truncated file is still rebuilt. The store's
header is also serialized in sorted key order now: two identical cold runs used to write
different bytes because aHashMap's iteration order leaked into the file.docheckresolves--helpprobes across cores. Every (binary, flag) pair spawns the tool
once — git's help path dragsmanand its formatter along — so 2,771 child processes ran
serially. The probe loop was already isolated from finding emission, so it now fans out over
the available cores with indexed results. Output byte-identical,npm run doc:check
3.0 → 1.9 s on four cores.benchmark/runs/is no longer gitignored. Run records are cited fromdocs/native-tools.md
anddocs/rust-tools-architecture.md, so ignoring the directory broke every link to a committed
record. The scaffold test now asserts the directory stays trackable instead of asserting the
ignore line.
Removed
skills/llm-format-checker. Its rule set duplicated theAGENTS.mddocs style that
skill-manageralready enforces; the skill was deleted, its row dropped from
docs/skills.md, and its auto-apply instruction replaced with the style rule itself.
Docs
docs/rust-tools-optimization.md— the repeatable path for optimizing a native tool: model
the cost by stage, freeze the old binary as an oracle, pin the seam before swapping it, run the
verification ladder, measure with interleaved A/B next to a published noise floor. Worked
examples carry measured deltas, alongside the traps already paid for (stale daemons, compaction
budget vs the gate cap, state that goes dead after the scan).- Plan §10 records measured handler cost (96 µs mean per tool call), §11 the session-log
measurement (223 sessions, 16,249 calls, 3.7% blocked, AG2 owning 42% of anchor blocks), §12 the
AG2 watch decision. - Validation table corrected: stale
plan:line references (+6 offset), V6's stated reason (a
9-byte literal against a 10-byte window is a dead comparison, not a compile error), V7's line,
V14's evidence, and the absent V12 row. §8's "no binary input channel" narrowed to "no channel
for compressed text", with binary-media billing and prompt caching added. - Repeat-call metric corrected from 399 to 70 after the
pidxparam-hash recount; the earlier
signature-based count conflated separate edits to the same file.
v1.61.0
What's Changed
Added
- Anchor Guard repeat-miss hint. The 2nd+ anchor block on one file within a user turn appends a loop-break hint (
piread the exact target lines, then resend once) to the block reason; count resets per user turn and on compaction (shares LG1's reset). Motivated by audit v2: anchor blocks are the top LLM error class (94/wk) and churn turns (>=4 same-path edits) hold 27% of all blocks+errors. Measured: gate 289/289 (1 new case); audit v2 basis 397 user-turns, 132 blocks, mistake-turns avg 12.7K out-tok vs 2.8K clean. scripts/session-audit.py— the turn-by-turn, byte-level session audit (v2) moved into the repo from /tmp: per-user-turn ledger of in/omitted bytes, elision + spill, usage tokens and cost, gate blocks by family, re-fetched read lines, duplicate commands, churn; full JSON to.cache/session-audit.json. Stdlib-only python3;fd --newer <date>scoping. Measured: week rerun from the repo reproduces the report (64 sessions, 397 turns, $62.73 basis).
v1.60.0
What's Changed
Added
- R1x (
reReadConsume) revived as the partial-overlap re-read rule. Replaces the old inert self-expiring-dedup semantics (never enabled, zero resend-loops in a week of sessions).warn(new default) appends a non-blocking note when ≥50% of a read's rendered lines were already in context and the file is stat-fresh;errorblocks at call time on the requested window and also catches same-batch sibling reads of the same path (the batch-slip shape). Threshold from the 2026-10-26 session audit. Measured: 288/288 gate cases + 28/28 gate-config (6 new); audit basis 149 ≥50%-overlap re-reads/wk (~2.6K re-fetched lines) vs 94 at 70%, 35 R1 catches, 6 same-batch dups across 33 sessions.
v1.59.0
What's Changed
Added
- LG1 loop guard — action-side stop conditions (1b). Evidence-first redesign: a week of this repo's sessions showed the grind is same-target churn (worst: task.md ×9, index.ts ×8 within single user-turns) while consecutive-error streaks never exceeded 3 — so error-streak thresholds would never have fired. LG1 notes (non-blocking, rides the tool_result) at the 4th landed same-path edit/write in a user turn; the 7th arms a one-shot block of that path's next mutation ("summarize what you tried, then ask the user"); 3 consecutive tool errors note once. Counters reset per user turn and on compaction;
loopGuardis config-switchable like every rule. Measured: permission-gate 284/284 PASS (4 new LG1 cases), gate-config 26/26 PASS, typecheck + agents-lint + doc-check clean; rule count 22 → 23 (README map corrected). - Circling-check behavior rule.
AGENTS.mdWorkflow & TDD gains the behavior-space mirror: same file edited 3+ times or the same failing fix retried twice in one turn → stop, state what remains and what failed, ask before continuing. The gate arrests a loop mid-spin; this rule teaches the finish the gate cannot. Measured: AGENTS.md 4,703 → 4,868 bytes; agents-lint 34 bullets, 0 dup/contradictions; doc-check 4/4 clean.
Changed
- Dedup + shrink pass on
AGENTS.md+SYSTEM.md. Removed intra-file duplicates (header restated the section list; TDD bullet restated itself; the two Completion bullets overlapped), cross-file duplication (tool list and.nvmrcchain lived in both headers — SYSTEM.md is their one home), and filler wording ("advanced", "high-speed", restated ask-first clauses). Measured: AGENTS.md 4,868 → 4,349 bytes, SYSTEM.md 3,630 → 3,500; agents-lint 33 bullets, 0 dup/contradictions; doc-check 4/4 clean.