Repository navigation
0.0.36 — 2026-10-12
v0.0.36 — development line, package release not yet published.
Verified source progress is committed and pushed tomainautomatically;
package publication and release tags remain separate operator actions.
This bump opens the dated heading so post-release work
accumulates in one place, per the no-unreleased-accumulators ruling: the
researcher-acceptance and lesson-feature-pipeline closures, the managed
scratchpad and provider-inventory passes, and everything else that lands before
the v0.0.36 cut. Release notes are written here at cut time; nothing in this
section is a package-release claim until then.
Release-audit closures (closed 2026-10-19)
- FID-2026-1018-010 — low — Preserve clickable child identity. The shared
clickable normalizer scopes React child identity withReact.Children.toArray
before flattening, so staticButton/CommandPaletteandFollowupLine
siblings stop reporting missing unique keys while explicit keys inside nested
arrays stay distinct. Host children stay non-selectable and no fragment is
introduced. Implementation:0c50fa8e; focused suite 5 pass / 0 fail, CLI
typecheck and scoped ESLint clean. - FID-2026-1018-011 — medium — Bound shared UI event subscriptions. Renderer
resize/focus/blur and ancestor scrollbar change now share one native
subscription per emitter and event, with independent consumer tokens; dispatch
snapshots its initial subscribers, skips removals and postpones additions, and
the native listener is released with its last subscriber. Thirty real animation
consumers keep their resize/focus behavior and return to baseline listener
counts across three mount/unmount cycles. Implementation:106ee6f8; 5 pass /
0 fail, 41 assertions. No operator-terminal observation is claimed by the
native render tests; LIVE-004's warning residuals stay tracked separately. - FID-2026-1018-013 — medium — Audit lifecycle and tooling hygiene. Standalone
probes execute only at their entrypoints, the console-capture and
exit-provenance diagnostic resets are wired into the CLI preload, and
object/native-FFI state carries exact self-validating lifetime exemptions
instead of a global audit suppression. Skill-evolution output moved under the
managed scratchpad active tree, audit-evidence tests run from their own
workspace, and two stale exact ledger-size pins became the audited minimums
they already described. Implementation:20b2f55c; scripts suite 1,122 pass /
0 fail. - FID-2026-1018-014 — high — Dependency advisories and unused packages.
Removed seven unused backend/native packages, upgraded vulnerable direct and
transitive pins, kept the compatible Zod 4.4.3 pin, adopted the
ESLint-9-supported typescript-eslint line while preserving the prior
catch-binding policy, and replaced two type-only runtime schemas with static
types. Persisted Bun patches bound the braces parser depth at 128 and map
gray-matter's YAML-4 engine names; a durable hostile-input probe now runs first
in the pristine-install bundle gate. The registry audit fell from 25 affected
names to one patchedbraces@3.0.3finding with no upstream fix — mitigation,
not a zero-advisory claim — and the SDK distribution stays unpublished.
Implementation:60c50a67. - FID-2026-1018-012 — medium — Release-audit reconciliation. Current docs now
match shipped behavior: the wheel/scrollbar picker claims that the allocator
repair removed are corrected, SDK installation is described as source-pinned
while its distribution stays unpublished, the scaffold examples are named with
their real consumer, and the ignored local dev links were replaced with
reachable sources. Archived records gained machine-readable commit evidence,
the configured recovery destination is reported instead of an unobserved
"OneDrive-synced" claim, andSCOPE.mdwas reconciled with the closed children.
The 0.0.36 heading moved above its own recent entries as a byte-identical
relocation, soextractChangelogSectionno longer drops the newest picker,
worktree and provider notes from generated release text. Implementation:
789ec02c.
Committed slices re-ran the hard gates: 14-workspace plus scripts typecheck exit
0, CLI 4,233 pass / 18 skip / 0 fail, scripts 1,122 pass / 0 fail, ESLint 0
warnings, Markdown lint exit 0, validate:repository PASS.
Session-summary month organization (closed 2026-10-19)
- FID-2026-1019-001 — low — Group session summaries by month automatically.
dev/session-summaries/held 367 dated artifacts (22 in 2026-07, 93 in
2026-08, 78 in 2026-09, 174 in 2026-10) in one flat directory. The SessionEnd
review now moves every dated root-level file into itsYYYY-MM/bucket —
canonicalYYYY-MM-DD-*names and the pre-conventionYYYY-MMDD-*shape
alike, and dated logs/screenshots with them — without renaming or rewriting
one byte. Planning is pure, so--checkand--dry-runreport exactly what
the apply path does; an existing destination is reported and never
overwritten; a second run is a no-op; the step fails open so organization can
never break the review. Records that cite a summary by its old flat path
(LIVE-003 evidence, the canonical learning rules, LF-005, live docs) still
resolve through a directory-scoped fallback, so historical citations were not
rewritten. The 12 summaries tracked in git moved as 100% renames. Gates: 13
unit tests pass, scripts suite 1,135 pass / 0 fail, scripts typecheck and
ESLint clean,validate:repositoryPASS (six pre-fix reference failures
gone), and a probe summary was grouped by a real SessionEnd run.
Implementation:53c270da.
Repository hygiene and docs/data parity (closed 2026-10-18)
- FID-2026-1018-007 — medium — Audit storage and reconcile current guidance.
Corrected README development callouts, SDK/local-agent examples and API docs,
testing guidance, malformed/dead links and design-generator version metadata.
Preserved old scope history outside the active register and untracked a
174,027-byte regenerable Sigma intermediate while keeping its local copy.
Audit:docs/reports/repository-hygiene-audit-2026-10-18.md.
Implementation:463d8096; 11/11 declared gates and SDK build pass; all 166
JSON-family files validate with their domain parsers, all 74 design resources
pass production integrity checks, and current-doc link checks pass. Large
ignored reference/dependency trees stay; external-home diagnostics remain
operator-owned. This is source progress, not a release or publication claim.
2026-10-19 — Stop /model from blanking the CLI (FID-2026-1018-008, critical)
Opening the model picker emptied the screen while the process kept running and
painting frames. The console channel was blocked: OpenTUI replaces
console.error during activation, so the failure text went to an overlay the
app never opens. Re-wrapping console capture on top of OpenTUI named it —
mounting 4,075 native rows returned null from createTextBuffer, React threw
in completeWork, the error boundary's <text> fallback failed identically,
and React unmounted the root. The picker now mounts only the window
getPickerViewport already computes. Measured with a new dwell probe on the
real catalog: before, the picker never appeared and render-tree-empty fired at
8 s; after, it opens, survives a 26 s dwell, and the session quits through its
normal exit path at 408 MB. Implementation: 24cf1bae. Operator acceptance
(LIVE-004): five /model opens on the same catalog during a live session with
three bashers running, none blanked, no render-tree-empty and no
TextBuffer failure recorded.
2026-10-18 — Credit a windowed boot read that reached EOF (FID-2026-1018-009, high)
A read_files call that carried limit earned no grounding credit even when
the whole file came back: limit: 2000 on the 923-line ECHO.md was read as a
partial window, so the required harness grounding set never completed, the
completion gate blocked three times, disarmed, and the turn ended with no tool
call. Credit now follows the window's effect — an offset past line 1 is
always partial, and a limit is partial only when the response used it up.
Three suites pass (27 tests), typecheck, ESLint, Prettier, Markdown lint and
validate:repository are clean. Implementation: 59d6226f.
2026-10-18 — Clarify worktree busy-lock recovery (FID-2026-1018-006, low)
Busy advice now requires confirming no live lifecycle writer remains before
removing a confirmed abandoned, empty lock. An empty directory does not prove
abandonment. Lock behavior stays fail-closed; the existing suite checks advice
and preservation of empty/populated locks. Implementation: a9413a69;
3/3 declared gates, scoped Prettier and SDK build pass.
2026-10-18 — Validate worktree acceptance artifacts (FID-2026-1018-005, medium)
The instrument now wraps its proof, lints before commit and after merge,
uses a covered tracked-file change for discard, names shells for lock steps,
and reconciles unique-row counts. Run-4 report and qualified assessment are
preserved durably. Implementation: 72aefe15; 2/2 declared gates and Markdown
lint pass. Future runs require a new authorized active converged vehicle.
2026-10-18 — Accept the demonstrated live lane lifecycle (FID-2026-1017-008, low)
Run 4 demonstrated create, isolation, scoped writes/refusals, fast-forward merge,
first-attempt graph refresh, dirty refusal, explicit discard and busy refusal.
Proof merged as a99db5b8; MD013 repaired as e0d29fb0. All 15 acceptance
gates pass. The report's 34-PASS headline conflicts with 43 PASS table labels
and one substituted SKIP. The covered-file substitution and extra repair commit
remain explicit deviations; closure does not certify unchanged-instrument
conformance or the declared untested live paths. Retained branch/stash preserved.
2026-10-18 — Repeatable parallel-worktree acceptance preconditions (FID-2026-1018-004, medium)
Run 3 reached the live tool but used an already tracked proof, so the lane
stayed clean and disposal correctly succeeded. The next instrument uses a
run-unique proof with a matching scope grant and exact graph lookup, requires
observed dirtiness before refusal tests, checks both checkout states and refs
immediately before merge, and requires exclusive main access. Reports go under
scratch active. Retained branch/stash stay intact; preparation documents a
separately approved normal branch fast-forward when ancestry permits it.
Implementation: 59a0c0e5; 2/2 declared gates and scoped markdownlint pass,
with positive/negative read-only graph controls. Run 3's report/FID handoff is
preserved. Run 4 has not run; FID-2026-1017-008 remains converged and unaccepted.
2026-10-18 — Keep the model picker stable during agent updates (FID-2026-1018-003, high)
The model picker revisited the entire catalog on unchanged parent updates.
React memo now skips that work while changed queries, catalogs, selection and
store subscriptions remain live. The native regression failed before repair
and passes afterwards; existing keyboard, mouse, resize and open tests pass.
Implementation: dd57660c. Verification: 5/5 declared gates exit 0.
The reported blank screen with three active bashers was not reproduced. This
repair reduces confirmed render load; it does not establish the incident's
cause or certify live recovery. Initial mount still allocates the full catalog.
Original incident acceptance remains tracked as LIVE-003.
2026-10-18 — Worktree results use traffic-light chrome (FID-2026-1018-002, low)
fid_worktree was absent from the CLI renderer registry and fell through to
the generic tool block. It now reuses the existing structured traffic-light
panel through loading, results, refusals, folding and empty output. Native
ToolBranch coverage exercises all four actions and narrow width without
performing lifecycle mutations. Implementation: 50f5877f. Verification:
4/4 declared gates exit 0; the related MCP native fixture also passes.
2026-10-18 — Document that Zylo's catalog needs no key (FID-2026-1018-001, low)
The SDK environment reference annotated the BlazeRail and River keys but not
ZYLO_API_KEY, which hid the one property that distinguishes it: the live
catalog is fetched publicly and the key authenticates inference only. The
reference now says so beside the variable, naming
https://api.zyloai.net/v1. Generated artifacts are untouched — the provider
doc generator reports all four unchanged.
Implementation: 00fa0959. Verification: 3/3 declared gates (provider-doc drift
probe, registry setup suite, quality), markdownlint and Prettier pass.
2026-10-17 — Add Zylo AI as a text-only public gateway (FID-2026-1017-016, medium)
Zylo is available through /provider zylo with ZYLO_API_KEY and
OpenAI-compatible chat at https://api.zyloai.net/v1. Its catalog is
keyless: the public /models roster supplies all 126 text rows, including
sparse capability metadata, while image and custom sub-model arrays are
excluded. Every published row keeps a positive finite window, the fetch sends no
Authorization header, and the provider takes ladder slot 18 ahead of the custom
tail. The census is preserved in docs/reports/zylo-provider-live-check.md.
Plan entitlement and live inference were not obtained and are tracked as an
internal follow-up, so no access claim is made.
Implementation: e22c06bf. Verification: 10/10 declared gates pass; full
repository test chain, typecheck, ESLint, markdownlint, Prettier and repository
validation pass.
2026-10-17 — Add River AI as an authenticated gateway (FID-2026-1017-015, medium)
River is available through /provider river with RIVER_AI_API_KEY and
OpenAI-compatible chat at https://api.river.ai/v1. Its live catalog is the
account's own model list, kept with exact upstream IDs under the river/
routing prefix; the three documented 1,048,576-token windows are pinned and
undocumented windows stay unknown rather than invented. Exception ownership,
window coverage, fan-out, cache reset, setup/SDK contracts and generated docs
ship in the same change, at ladder slot 17. The identity gauntlet remained
inconclusive, so route reachability is reported without an identity claim.
Implementation: e22c06bf. Verification: 12/12 declared gates pass; full
repository test chain, typecheck, ESLint, markdownlint, Prettier and repository
validation pass.
2026-10-17 — fid_worktree is callable again (FID-2026-1017-014, high)
The second parallel-worktree acceptance run could not invoke the tool: every
call was refused before dispatch with invalid_union. fid_worktree was the
only tool whose parameter schema had a discriminated union at the root, and the
AI SDK serializes that as { oneOf: [...] } — no top-level type: 'object',
no properties. The provider therefore advertised no fields, the model emitted
{}, and the runtime correctly rejected it. The schema is now one flat strict
object (action enum, optional fid_id / discard_changes) with the
per-action rules in superRefine, which never reaches the wire schema. Every
refusal the union encoded is preserved: unknown keys, missing fid_id,
discard_changes outside dispose, malformed ids. A new class guard fails any
tool whose provider-facing root is not an object, so this shape cannot return.
Implementation: 0dad50e5. Verification: 6/6 declared gates (params suite,
object-root guard, agent-runtime tool and provision suites, real-git probe,
quality), dispose/merge/environment suites, root typecheck, ESLint and
markdownlint all pass. The live lane lifecycle is still unexercised — the third
A–Z run is the acceptance step.
2026-10-18 — Add BlazeRail as a built-in gateway (FID-2026-1017-013, medium)
BlazeRail is available through /provider blazerail with the registry-managed
BLAZERAIL_API_KEY and OpenAI-compatible chat at https://api.blazerail.com/v1.
The public catalog supplies 183 filtered chat/coding rows; media rows are
excluded, published windows/output limits/pricing are retained, and unknown
windows stay unknown. Tests confirm exact upstream namespaces and :free /
:nitro suffixes remain intact. No key or inference request was used, so account
authentication and live model acceptance remain unverified.
Implementation: 8741613e. Verification: all 10 declared FID gates pass; full
repository typecheck and test chains pass, along with ESLint, markdownlint,
Prettier, repository validation, provider-doc drift and quality checks.
2026-10-17 — Parallel acceptance run is repeatable (FID-2026-1017-012, high)
The unsafe-root guard could not tell "git never ran" from "git reports another
root": both refused with the same message, and 3 of 18 live lifecycle calls were
refused in the acceptance run. The guard now retries once only when the process
could not run (status: null); a reported root must still match, and a non-zero
status still fails closed. The A–Z instrument is corrected for the four
divergences its own run recorded (empty baseline, force-added FID record,
schema-first invalid-id refusal, dispose recovery warning), and a paste-ready
video draft is exempted from MD013 so the mandatory lint gate runs again.
Implementation: 4f989510. Verification: 5/5 declared gates (agent-runtime
typecheck, tool suite 7/7, provision suite 5/5, real-git probe, quality), ESLint
0 warnings, markdownlint exit 0, repository validation PASS. Lane prep: the
contained stale branch was deleted and the blueprint stashed for restoration
after the run.
2026-10-17 — Post-merge graph refresh survives real assets (FID-2026-1017-011, high)
The parallel-worktree merge landed but its main-graph refresh threw, so the
merged file stayed out of .savant/graph.db until an operator ran
/graph refresh. Two defects were reproduced in sequence. First, the index
scan applied the 1 MB cap to the UTF-8-decoded string: invalid bytes decode to
U+FFFD (three bytes each), so four tracked assets under 900 KB on disk expanded
past the cap and aborted the scan. Second, the write phase collided on
file_extends (file_id, parent) because one file may declare several children
extending the same parent; six tracked files do exactly that. The cap now
governs on-disk bytes only, and extends relations dedupe by parent to match the
persisted key. Two regression fixtures were added; the live refresh completes
in 8,894 ms and the merged lane proof is present in the graph.
Implementation: 774eb705. Verification: fid:verify ran 7/7 declared gates
with exit 0 (knowledge-graph and agent-runtime typechecks, refresh-safety,
edges-from-tokens, fid-worktree-environment, the real-git lane probe, and
quality). The open BLOCKER-2 from the FID-2026-1017-008 live acceptance run is
repaired; that run's own record still awaits the operator re-run.
2026-10-17 — Coding-focused free options (FID-2026-1017-010, high)
Boot and /provider free now share purpose, expiry and duplicate filtering.
Specialist model tasks, unrelated offer categories, expired/unresolved deadlines
and unsafe offer links stay in the broad discovery report. Structured text/tool
metadata survives cache round trips; missing metadata remains explicitly
unverified. Correct the existing VL-name boundary for whitespace and :free.
Expanded boot output and Copy share a preview capped at five models per provider
and five offers, while header counts retain the complete selected totals and
filtered reasons. The artifact retains the full discovery evidence and hash
contract. Implementation: cc0c2913; ten declared gates pass, with native-render
coverage, 78 focused tests, CLI typecheck and SDK build. No live capability,
quality-ranking or account-quota verification is claimed.
2026-10-17 — Preserve dependencies during lane disposal (FID-2026-1017-009, critical)
Windows Git follows dependency junctions during worktree removal and can delete
main-checkout package files. Detach symbolic links and junctions without following
their targets before recursive lane teardown; refuse cleanup if detachment fails.
The protection also covers recordless cleanup and initialization rollback.
Implementation: ab021ebf. Four new regressions reproduce the original failure
and pass after repair; the combined lifecycle suites pass 19 tests. All six FID
gates, full root typecheck and SDK build pass. Restored the local installation
from the unchanged frozen lockfile and verified CLI help starts successfully.
2026-10-17 — FID-bound parallel worktrees (FID-2026-1017-007, high)
Complete the eight-step worktree feature: lane-local Law 2 scope with validated
git registration and symlink containment, an Orchestrator-only fid_worktree
tool, clean fast-forward integration with conflict/divergence refusals, stable
execution slots and isolated command environments, WAL-aware graph snapshots,
post-merge graph refresh, orphan reporting and the shared operator CLI. Child
commands retain the SDK environment allowlist. Lane selection is explicit;
conflicts are never resolved automatically and no speedup is claimed.
Implementation: 11dd667d, following the lifecycle foundation at 7618b5b4.
All 15 declared FID gates pass, including the two-lane real-git/SQLite probe;
the full root test chain, root typecheck, SDK build and repository checks pass.
The operator guide is docs/design/parallel-worktrees.md. The source/built
ripgrep regression pins also check the resolved binary's SHA-256, so building
the SDK no longer creates a false gate failure.
FID closure and archive: dc2953f0. Session-end review completed; the final
verification and closure record is
dev/session-summaries/2026-10-17-fid-worktrees-completion.md.
2026-10-17 — Boot free-options panel renders natively (FID-2026-1017-006, high)
Every boot replaced the free-options panel with the transcript error fallback
— "This content could not be displayed. Your session is still active." —
followed by the block serialized as raw JSON. The panel opened
TrafficLightPanel with a literal {' '} string child; OpenTUI's reconciler
rejects text outside a <text> node, so FreeOptionsPanel threw
Text must be created inside of a text node and the boundary printed
JSON.stringify(blocks) as its preview. The spacer is gone; the panel mounts
on the reconciler that actually renders it.
The suite shipped with FID-2026-1017-005 could not see the defect because it
renders through react-dom/server, where box and text are custom elements
and host invariants are not enforced. A native-render suite now mounts the
panel collapsed and expanded on @opentui/core/testing and rejects the
fallback, the serialized block and a missing header — proven red with the
child restored (2 fail) and green without it (2 pass). The operator's real
cached report (146 models on 3 wired lanes, 2 not-wired tiers, 1 local lane,
223 offers) was also mounted natively at 120 columns in both states: header,
counts and every expanded section rendered with no fallback and no raw JSON.
Implementation: 907e04f8. Verification: fid:verify ran all 5 declared
gates with exit 0 (typecheck cli, both panel suites, the collapse suite,
quality); static panel and collapse suites 15 pass / 0 fail.
2026-10-17 — Fresh, complete free-options boot panel (FID-2026-1017-005, medium)
The boot digest was reading the free-options cache synchronously before the
provider refresh it depended on had run, so an expired boot showed expired
values; it then printed two offer titles and pointed at free-options.md by
bare filename. It is replaced by a TrafficLightPanel transcript block that
resolves freshness before posting: a cache no older than 12 h is shown with its
exact age, an older or absent cache gets one bounded refresh (6 s over the
existing 5 s fetch timeout) through the existing single-flight, and a failed
refresh serves the cache labelled STALE instead of current. The panel is
collapsed by default and expands to every wired and not-wired model id, every
local lane and every advertised offer.
The panel, the markdown export and /provider free now derive from one
buildFreeOptionsView, so their counts and payloads cannot diverge. The
artifact carries its resolved path, generatedAt, fetchedAt and a body hash;
the boot reader verifies path, catalog vintage and hash, and a copy in another
config directory is rejected. A failed export is returned and rendered in both
the panel and the command instead of being swallowed on the false premise that
the command output was already complete, and the command names the resolved
absolute path rather than a bare filename.
Implementation: 33a58d63, plus 7db948bd for fail-silent boot setup.
Verification: fid:verify ran all 10 declared
gates with exit 0 (cli typecheck; the boot, view, panel, collapse and renderer
suites, 62 pass / 0 fail; the durable boot-artifact probe; the scripts
typecheck probe; quality); the full CLI suite is 4174 pass / 28 skip / 0 fail,
the root typecheck is exit 0, and validate:repository passes. No live TUI
smoke ran because tmux is not installed in this environment; the boot path is
pinned at the resolver/handler boundary and the panel through a static render.
2026-10-17 — Bounded research spawn contract (FID-2026-1017-004, medium)
spawn_agents now accepts an optional typed research plan and enforces it on
the production path. A plan pins the objective, turn identity, captured source
bytes and snapshot digest, per-step sources and dependency edges, and an output
ceiling. Validation is all-or-nothing against real bytes; dependency stages run
in order behind the existing aggregate barrier; the host injects each
predecessor artifact and accepts a step only on verified read_files bytes and
that exact artifact's presence in the child history. Plan steps are read-only
research roles, so implementation, audit and effectful roles are refused before
dispatch, and a stale turn or an over-budget ceiling is refused too. Rejected
and cancelled steps report an explicit error and keep the credits they spent.
Spawns without a plan keep the previous behavior, partial filtering included.
Implementation: 267be888, plus a follow-up that forwards the plan's output
ceiling into every child request (the tighter of the plan ceiling and the run
budget applies). Verification: fid:verify ran all eight declared
gates (typecheck common and packages/agent-runtime, the three plan suites, the
deterministic probe, the scripts-tree typecheck probe, quality) with exit 0;
the full agent-runtime suite is 2218 pass / 0 fail. The plan's source contract
covers local files only; web sources and nested plan descendants remain outside
it, and no latency, reliability or monetary claim is made.
2026-10-17 — Bounded research workflow selection (FID-2026-1017-003, low)
Added equal-final-brief comparisons for consolidated investigation, independent
fan-out and the dependent research chain. Real Apixo gpt-6.1-sol results:
41.230 s / one send, 90.202 s / four, and 91.603 s / four, respectively. All
selected evidence checks passed; the fastest draft was rejected semantically
for proposing that stale costs be ignored. Fan-out's timing difference is
inconclusive. Actual tool-result bytes are now required for every assigned
source, rather than attempted read paths alone. Twenty-five controls pass.
Executed two fresh draft/review trials after the operator authorized four
additional sends: 89.142 s and 63.511 s, two sends each, all source-read/handoff
checks passing. Review retained cost and mandatory-review constraints, but
residual parent-overlap and Forge-for-research proposals prevent blind semantic
acceptance. Selected a host-enforced bounded research contract and documented
the product integration/acceptance map in docs/design/parallel-workflow-decision.md.
Research implementation/evidence commits: bfcb3640, e0f113a5; seven declared
gates pass. FID closed and archived; scope released. The cumulative 64-request
ceiling is exhausted. Closure covers research and the executable prototype;
no production installation, general speedup or monetary saving is claimed.
2026-10-17 — Validated parallel handoffs (FID-2026-1017-002, low)
The isolated research scheduler now validates a complete returned wave before
publishing results or releasing dependencies. Host-issued source references bind
exact citation locations/text; predecessor digests come from actual handoffs.
Downstream reviewers receive predecessor source files. Raw drafts and rejected
mode outcomes are retained. Implementation: 0292beba; six FID gates pass,
including 19 control tests / 87 assertions.
A real Apixo gpt-6.1-sol pair completed with zero selected citation/handoff
failures: batch 96.997 s, completion 89.762 s, four inference sends each. Exact
predecessor artifacts reached the appropriate downstream histories. B finished
before A in both modes, so there was no useful overlap or demonstrated speedup.
An intermediate five-send pair rejected altered quotes before publication.
Cumulative sends are 51/60; nine unused. Mechanical consistency does not establish
semantic correctness or production async readiness. Details and next candidate:
docs/design/parallel-agent-slice.md. No production migration or release.
2026-10-17 — Live parallel-agent research slice (FID-2026-1017-001, low)
Added an isolated executable comparison using the actual SDK, spawn handler,
source-read tools, Apixo gpt-6.1-sol, and experiment-owned SQLite. The store
checks duplicate delivery, transactional consumption, cancellation generations,
and interrupted attempts; transport caps actual sends and holds concurrency
permits through stream completion. Five declared gates pass, including ten
control tests. Implementation: 8244dc9c.
Both real four-task schedules completed: batch 233.895 s, completion 166.292 s,
four inference sends each. B finished before A in both modes, leaving no
early-release opportunity; the timing difference establishes no scheduling gain.
Batch failed 13 quotation checks; completion failed seven quotation checks and
one exact handoff digest. The report retains those failures. The runner now
returns a failing exit status for failed evidence after preserving both modes.
Total inference use, including earlier upstream failures: 38 of 60 permitted
sends. No measured dollar cost or production-readiness claim is made.
Reproduction, results, and limitations: docs/design/parallel-agent-slice.md.
2026-10-17 — The trusted skill catalog and its trigger cases are reconciled (FID-2026-1016-019, medium)
Five failures in the evals lane were pre-existing but sat inside the pre-push test chain, so they refused
the FID-018 delivery. Three trusted skills had shipped (FID-2026-1016-015 lane) without a trigger case
file; release-workflow's case still pinned the pre-rewrite description hash; and the quarantined-drafts
assertion required draftCount > 0 although the operator ruling deliberately emptied .quarantine/.
This change authors the three case files with behavioral rubric items, re-pins the intentional description
hash, and restates the draft rule as a contract (drafts, when present, are advisory — never a CI error)
instead of a catalog-state expectation. Verification: fid:verify receipt 6/6 PASS, evals lane 229 pass /
0 fail, eslint and prettier clean; commit 8d735d34. Prettier-only formatting also lands on four files.
2026-10-17 — Ashna joins the built-in registry as a keyed live gateway (FID-2026-1016-018, medium)
ashna.ai is now a first-class provider end to end. Live probes measured the
vendor contract (keyed-only catalog — 401 keyless, 200 authenticated, 104 rows
with no window or name fields, roster moving between probes) and a plan-gated
inference leg (429, envelope recorded verbatim in the FID; unblocks with zero
code changes on a paid plan). The change adds the registry entry (openai
protocol, strip transform, order: 4), the keyed parser wrapper with local
retrieval/image exclusions (78 of 104 retained), the 17-slot settled-ladder
fan-out + merge spread + reset seam, the table-section window registration
with 28 cross-gateway consensus rows and 50 documented no-row ids, the
live-catalog manifest owner, derivation legs, generated + hand doc surfaces,
and the census regen (ashna: 78). Verification: fid:verify receipt 17/17
PASS; full suites common 912/0, cli 4147/0, sdk 719/0; probes reconciled;
commit cc544ea3.
2026-10-17 — Acceptance is recorded per run, and every rule's authority reference is resolved (FID-2026-1016-016, FID-2026-1016-017, medium)
The second ruling round selected both unselected lesson features. They shipped in one commit
(ec60a108) but under two records, because the feature register admits one owning FID per
candidate — LF-005 and LF-006 could not share an owner, and the register said so rather than letting a
merged record imply otherwise.
Added
- Acceptance is now an artifact, not an inference from tool success (LF-005). Every tool call in a
run can return while the feature is still broken for a person: the report confirms a command exited,
never that the terminal rendered, that resize reflowed, that the transcript folded, that an export kept
its last row, or that a resumed session showed what it claimed. Regression tests do not close that gap
either —cli/src/components/__tests__/transcript-recovery.render.test.tsxproves the deliberate-error
path, a different claim from "this run behaved for a human". Acceptance is therefore a run-bound record
atdev/tracking/acceptance/<runId>.json, built from a template that claims nothing
(bun run acceptance:check --template <runId> <sessionId>) and read back bybun run acceptance:check
(scripts/production-acceptance.ts,scripts/acceptance-check.ts,docs/production-acceptance.md).
Each of the five UI surfaces —resize,input-responsiveness,folding,copy-export,
resumed-history— carries exactly one outcome, so no aggregate "it works" stands in for a surface
nobody looked at; a claimed outcome carries its observation and resolvable evidence;unverified
carries no observation at all, which is what keeps the word honest; a record with any claimed surface
must contain at least one operator/native check;automatedRegressionentries must name a test file that
exists;runIdmust match the file name; andsessionId+callLedgerbind the record to the ledger
holding that run's failures and fallback steps.validate:repositoryruns the same collector, so a
malformed record fails the repository gate.
Changed
- The canonical rule catalog is re-resolved against the tree (LF-006).
dev/LEARNING-RULES.mdnames,
for each rule, the artifact that authorizes it and the check that validates it — and nothing resolved
those references, so abootrule could keep citing a deleted file or a FID that never existed. A dead
artifact or FID reference is now an error in a current (boot/reference) rule and a warning in
ahistoricalone; that asymmetry is the visible distinction between dated guidance and current
authority, and hiding the historical case would have thrown the information away while failing it would
have treated history as policy. A rule whose tier disagrees with the status of its linked lessons is
refused in both directions, and rules with no linked lesson are deliberately not judged (23 of the 35
real rules). Measured before wiring: 62 artifact and FID references across those 35 rules, 0 dead, so
the check fails only on real decay (scripts/learnings-staleness.ts, wired intobun run learnings:check). - Admission refuses to re-implement what an implemented candidate already owns. The register already
refused an identity collision and an FID shared between two candidates, but a new candidate with a
new identity and a new FID naming the same work passed every check. Titles are now compared
normalized against the implemented archive and the refusal names the owner
(scripts/lesson-feature-admission.ts). Stated as a boundary rather than a guarantee: a title rule is a
detection floor, not a proof of non-duplication — a duplicate worded differently still passes.
Notes
- The LF-006 record exists separately from the LF-005/LF-006 authoring record for the reason above, and
carries its own stamped receipt over the same implementation commit.
2026-10-17 — Skill drafts carry the lesson, four drafts trusted, the live-comparison item retired (FID-2026-1016-015, medium)
Changed
- Auto-drafted skills now teach the lesson instead of the failure message. Before trusting the four
quarantined drafts the operator ruled on, reading them showed that
library-complete-needs-a-named-consumercontained no lesson at all: its description wasread_files'
error string sliced at 60 characters (…retry the tool cal) and its Procedure was its own name. The
drafter inscripts/lessons-to-skills.tsbuilt every draft from the recurrence row — description and
"When to Use" from the error text, Procedure from the canonical rule's slug — while its own comment
already claimed it carried "the candidate's REAL content … the actual lesson". The lesson'sinvariant
andguardwere parsed and then dropped, so they never reached the isolated drafting turn either
(CandidateHandoffInputhad no fields for them). They now travel candidate → proposal payload → drafting
prompt → draft body, and descriptions come from the rule, clipped at a word boundary under the
60-character agent-authored cap (the cap is why the old code sliced, and slicing is what cut the word in
half). - One lesson yields one candidate.
findCandidatesemitted one candidate per recurrence ROW, so a
single lesson reached the draft path as six proposals with fragmented counts (48×, 27×, 25×, 21×, 14×,
11×) and six payload hashes — which is also why the store's documented one-proposal-per-session contract
had never been exercised there: nothing looked like a second proposal. Counts now aggregate onto the rule
anddistinctSessionsstays the strongest single row's figure, because summing sessions would inflate the
promotion gate's own number. - All four quarantined drafts are trusted (operator ruling). release-workflow 0.1.0 → 0.3.0 (no
baseline pin, so trusted without drift verification — stated in the result rather than implied),
minisign-pubkey-vs-secret-keyv0.1.1,fid-gates-unfenced-parser-contractv0.1.1 and
library-complete-needs-a-named-consumerv0.1.0, each with atrustentry in itsVERSIONS.jsonland
its reason naming the ruling..agents/skills/.quarantine/is now empty. The corrupt draft was
re-authored fromdev/LEARNINGS.mdfirst, with its invariant, its two-step guard and Law 4 verification;
the pipeline cannot regenerate it, because that lesson's rule is deliberately unmapped from any failure
class (it is about FID closures, not a tool failure), andfindCandidatesreturns 0 against this tree.
Retired
LIVE-001closed NOT-PLANNED (operator ruling). Live provider comparisons are not planned: no paid
run happened, nothing was measured, and no comparison result is claimed — retiring the item is not
evidence of one. Reopening needs a future ruling that names the comparison references and numeric
call/spending limits. Recorded inSCOPE.mdand in the follow-up store whosestatusvocabulary has only
open/completed, so the disposition is spelled out in the summary rather than left to a status word.
2026-10-16 — Operator-ruled follow-ups: the Step-4 surface mounted, one robot design stated (FID-2026-1016-014, low)
Operator rulings on all nine open questions from the entry below, and their implementation.
Changed
- The skill-lifecycle traffic-light notice is mounted. FID-2026-1005-003 Step 4 wrote
cli/src/components/skill-lifecycle-notice.tsxand listed it as a CLI consumer, but nothing
rendered it — a mechanically created draft appeared only insession-end:reviewand
/skills activity, so the declared surface and the mounted surface disagreed. It now renders in
cli/src/chat/panels.tsx, in the ghost-message slot whose contract it shares: an empty row when
this surface has no unseen event, acknowledgement only after the render commits (at-least-once
replay on a crash), no raw tool or model prose (validated metadata fields only). The new suite
proves the render and pins the mount site, because the defect was an unwired component that
every unit test passed on. - The office cast states one design:
CAST_MODEL_URLSpluscastModelUrlForPad(a rotation
over a single model after the duplicate was removed) is now theCAST_MODEL_URLconstant, and
the orchestrator's "other model" offset is gone — Savant reads as distinct through its 1.55×
height and role accent. A genuinely different CC0 model would come with its own licence row in
ASSET-MANIFEST.md, as a new record. - Three hand-run probes moved to the documented durable probes home,
scripts/probes/:
desktop-cargo-test-probe.ts,learnings-prefix-probe.ts,learnings-truncation-probe.ts
(the cargo probe's crate resolution climbed one directory; thedev/LEARNINGS.mdcitations were
updated with it).scripts/orphan-sweep.tsnow namesscripts/probes/**as an exclusion class
with its reason in the header — a probe is invoked by hand and cited from the untrackeddev/
records, so "no mentioner" is not evidence there — and its advisory report drops from 17
candidates to 6, all of which are convention-loaded fixtures, examples or smoke assets that are
deliberately retained.
Removed
coding-standards/x402.md— the changelog already recorded its deletion (FID-2026-0717-003,
"agent payment standard, belongs in Savant core"); the file was still present. Removing it executes
that record rather than re-litigating it.
Deliberately unchanged (operator rulings, recorded so they are not re-opened)
- The other
quality:keys (max_function_lines,max_complexity,max_line_length,max_params,
max_comment_density,max_nesting_depth) stay advisory; onlymax_file_linesis gated. - Both copies of the language standards stay (
coding-standards/*.mdand
.agents/skills/coding-*/SKILL.md); they agree on the enforced ceiling, which is single-sourced
fromprotocol.config.yaml. WINDOWS.md'sIssue #NNNlinks stay marked unverified rather than presented as checked.website/index.htmland the two untracked operator files stay where they are — the operator:
"they are the official website design files being kept in the repo".
2026-10-16 — One tracked file-length ceiling, the duplicate robot model removed, 19 dead files triaged out (FID-2026-1016-013, medium)
Changed
- The file-length ceiling is one tracked number (operator ruling: 400 for every language). It was
read from the untrackeddev/quality-baseline.json(300) whileprotocol.config.yaml's comment
merely claimed to own it, so the most consequential quality number in the repository was
machine-local and unreviewable.scripts/quality-report.tsnow resolvesquality.max_file_lines
from the tracked config and fails closed — a missing block, a missing value or a non-positive
integer throws, because a ceiling nobody can see is worse than no ceiling — and the local baseline
no longer carries the key at all, so exactly one file states the number. Measured honestly: no
source file exceeded 300, so the old value was enforced and never bit; this change is about where the
policy lives, not about relaxing a violated gate. - The per-language override tables were fiction and are now removed. Six
coding-standards/*.mdand
six.agents/skills/coding-*/SKILL.mdfiles documented overrides (csharp/go/java 350, python 400,
rust 300, typescript 400) for a mechanism the report has never had; the TypeScript skill was the only
one telling the truth ("no file-length exemptions"). Each now shows one honest limits table: the
single 400 ceiling, enforced bybun run quality:report, every other setting marked advisory. The
same correction landed indocs/adding-a-provider.mdand the self-improving-architecture plan. SKILL_MAX_FILE_LINESwas a third real ceiling (common/src/constants/skills.ts, 300, enforced
byskills:checkon everySKILL.md). Now 400, mirrored from the config becausecommoncannot read
YAML at runtime, and pinned by a test (SKILL_MAX_FILE_LINES === readQualityCeiling()) so the two
values cannot drift apart silently.- The duplicate robot model is gone and its attribution corrected.
desktop/public/floor-assets/robots/robot.glbwas byte-identical toRobotExpressive.glb
(SHA-256047f5e5f…, 463,988 B) whileASSET-MANIFEST.mdcredited it to the Quaternius pack — and
both files' glTF JSON names the Khronos sample model's own meshes and clips (Foot.L,Torso,
Idle/Dance/Wave…), so the false row was the Quaternius one.robot-cast.tspresented the pair
as "two distinct designs" alternating across the pad ring, with Savant getting the other model from
its specialists — a distinction that never existed visually, because the bytes were one model. The
duplicate is deleted,ROBOT_MODEL_URL, the cast comment, the loader comment and the asset test
follow the kept name, and the manifest now records the removal and why. scripts/orphan-sweep.tsresolves two more reference spellings: the emitted-JS extension (this
tree imports its own TypeScript as'./audit-rebrand-corruption.js', so seven live modules were
reported as orphans) and directory-relative mentions (cli/bunfig.toml→./src/polyfills/x.ts).
Both deliberately trade false positives for false negatives: a human deletes files from this report,
so a missed candidate costs one stale file while a wrong one costs a deleted module.- The sweep now recurs:
bun run session-end:reviewprints one advisory line (count + the command to
run, never an exit code) andAGENTS.mddocuments the sweep. Measured cost 3.1 s, inside the
SessionEnd hook's 60 s timeout. It runs from the CLI entry point, not fromrunSessionEndReview, so
tests against temp roots never walk the real repository. WINDOWS.mdverified line by line against the source and linked from the README (it previously had
zero inbound references outside this changelog): the bash requirement andSAVANT_CODE_GIT_BASH_PATH,
the release-metadata failure, proxied release downloads and the update message all check out, and the
document now says whichfile:lineeach was verified against. One claim was false — see below.
Fixed
WINDOWS.mddocumented a launcher message that does not exist. The troubleshooting section
describedUpdate available: error → [version]and explainederroras a placeholder version; the
launcher printsUpdate available: ${currentVersion || 'unknown'} → ${latestVersion}
(cli/release-core/launcher.js:1236,:1278), so the placeholder isunknown, printed when the
installed version cannot be read. The section now says that, and the document records the correction
rather than quietly rewriting itself. ItsIssue #NNNlinks were not re-checked and are marked
unverified in the document instead of being presented as accurate.- 19 dead files deleted, after fixing the report that was supposed to find them. Every deletion was
checked twice: statically against a whole-working-tree corpus scan (git-tracked files plus untracked
dev/) using the sweep's own tokenizer, where the only mentioners were historical records
(archived FIDs, session transcripts, baseline line-count history) or the triage probe; and
dynamically, by typechecking and running the full suites of all four workspaces that contained them
(cli 4140 pass, common 911, desktop 473, packages/agent-runtime 2198 — 0 failures). Deleted:
cli/src/components/referral-quiet-line.tsx+referral-copy-button.tsx(the referral surface has
no other mention incli/src),cli/src/hooks/use-fingerprint.ts,
cli/src/hooks/use-sheen-animation.tsx,cli/src/polyfills/bun-strip-ansi.ts,
cli/src/utils/{error-messages,format-session-units,format-validation-errors-for-message}.ts,
cli/src/utils/syntax-highlighter.tsx,common/src/constants/{grant-priorities,subscription-plans}.ts,
common/src/util/{agent-file-utils,agent-name-normalization}.ts,
desktop/src/components/diff/parse-diff.ts,
packages/agent-runtime/src/find-files/custom-file-picker-config.ts(imports a module literally
namedold-constants), and four superseded ESLint fixtures (probe2.mjs,rule-test2.mjs,
debug-ast.mjs,unknown-good.ts— the live rule tests spawn their own probe since
FID-2026-1013-012 W3-5). - The local
dev/quality-baseline.jsonhad itsmaxFileLineskey removed and 13 entries pruned for
deleted files, so the history ledger no longer names files that do not exist. README.md's Windows note now points atWINDOWS.md.
Retained on purpose (17 orphan candidates, each with a reason)
Kept because a name index cannot see the reference, and deleting them would remove a capability rather
than a liability: hand-run smoke tools and probes whose invocation is manual and/or cited as evidence
by archived FID gates and dev/LEARNINGS.md (cli/scripts/graph-smoke.ts,
cli/scripts/hud-preview-browser-check.ts, scripts/desktop-cargo-test-probe.ts,
scripts/learnings-{prefix,truncation}-probe.ts,
scripts/providers/audit-probes/t62f1-commandcode-probe.ts,
scripts/__tests__/validation-manifest.parity-probe.ts); files loaded by convention
(evals/playwright.config.ts, evals/graph-export-e2e/playwright.config.ts, the two desktop
browser-smoke fixtures, common/src/templates/initial-agents-dir/examples/*); documentation examples
shipped to be read rather than imported (sdk/examples/readme-example-1.ts); and
cli/src/components/skill-lifecycle-notice.tsx, which is a declared-but-unmounted surface from
FID-2026-1005-003 Step 4 — the CLI renders skill-lifecycle events as plain text lines, so the traffic-light
component is dead code today, but deleting it would erase the evidence that the step was declared and
never wired. That gap needs an operator decision (wire it or drop it), not a hygiene pass.
2026-10-16 — Code search resolves the pinned vendored ripgrep again (FID-2026-1016-012, high)
Fixed
- FID-2026-1016-012 (high):
resolveCodeSearchRipgrephandedgetBundledRgPathits own
import.meta.url(sdk/src/tools/code-search/executor.ts), but every vendored candidate in the
resolver is expressed relative tonative/ripgrep.ts's directory (esm-dev=
<moduleDir>/../../vendor/ripgrep/…). From the wrong base all of them pointed at<sdk>/src/vendor/…
and missed, so code search fell through to a cwd fallback and aspawnSyncPATH probe instead of
using the pinned binary the same module documents as "the supported configuration" with priority.
Measured in one process with the resolver's debug sink: the correct base resolvesesm-dev→
sdk/vendor/ripgrep/x64-win32/rg.exe; the production call site resolvedpath-probe→
C:\ProgramData\chocolatey\bin\rg.exe, this machine's own install. On a machine withoutrgon
PATH, from-source code search failed outright; with one, it silently ran an unpinned ripgrep.
The call site now passes no URL, so the resolver uses the base its candidates were written for and
the vendored binary wins on the first candidate. Rejected the alternative of also trying the
module's own URL — a candidate list correct for two different bases keeps the trap. - The sdk suite failure that blocked every push is resolved as a consequence, not by touching the
test: the failing case was a symptom. With the vendored candidates skipped, each cold resolution
ranspawnSync('where rg')under a 1000 ms timeout, andsdk/test/setup-test-isolation.tsclears
that probe's memo in abeforeEach, so every test re-probed; under multi-file load the probe
exceeded its timeout (observed at 1016.81 ms) and resolution threw. Suite: 714 pass / 1 fail →
717 pass / 0 fail, and the new regression test dropped from 144.90 ms to 0.66 ms because the
subprocess probe no longer runs. - The regression test was written first and observed red (
Expected: true, Received: false) so it is
known to catch the defect rather than merely agree with the fix. Three competing explanations were
tested and refuted before the fix: a multi-fileimport.meta.urldifference,part-c's
child_processmock leaking into the PATH probe, and "any second test file".
2026-10-16 — Diagnostic logs are bounded, FID evidence stays durable, and the disk audit becomes repeatable (FID-2026-1016-011, medium)
Changed
- FID-2026-1016-011 (medium): a full disk audit measured ~15.5 GiB of reclaimable artifacts against
~30 MB of tracked content, and found one genuinely unmanaged sink.trimOversizedChatLogscovered
only the production per-chatlog.jsonl, while the dev sinks wrotedebug/cli.jsonl(45 MB) and
debug/trace.jsonl(166 MB) with no size cap, no rotation and no production reader — 287 MB
across three project roots. One cap constant now lives beside the paths it governs
(cli/src/utils/logger/file-sink.ts), dev writes go through a bounded append that rotates into a
single.1generation, and startup reclaims oversized idle debug files beside the existing
chat-log sweep, so each root is bounded at ~40 MiB.chat-history.tsimports the shared cap
instead of holding a second copy (Law 13). - The FID template and the verification-gates module taught a scratchpad evidence path
(- gate: probe dev/scratchpad/…) — a tree that expires 24 h after its last change and is
untracked. Measured: 18 archived records declared scratchpad gates and 3 of 4 sampled probe
files were already deleted by expiry, so those gates outlived their own evidence. The examples
now point at the tracked probes home (scripts/probes/), the protocol bundle is regenerated, and
scripts/hygiene.tsreports the shape asephemeral-evidencefor active records — scoped to
active because aclosedrecord is outside the gate contract and re-reporting history would make
the rule permanently red. - The scratchpad's own rules were made true: the
README.mdthatdocs/scratchpad.md,
common/src/util/scratchpad/scan.tsand the hygiene rule all named but that did not exist was
created;docs/scratchpad.mdandAGENTS.mdnow state the root shape, the 24 h expiry, the
<session|fid-id>-<what>.<ext>naming rule and that scratch storage is never evidence; and the
two inert.gitignorelines (dev/scratchpad/*,!dev/scratchpad/.gitkeep) were removed — git
cannot re-include a path below an excluded parent, verified withgit check-ignore -v. scripts/orphan-sweep.tsmakes the hand-run orphan analysis repeatable: 46 candidate files among
4,940 tracked, reported advisory-only because a name index cannot see runtime-built references.
Both defects found in it before it was trusted are covered by regression tests —
extension-sensitive matching missed every extension-less import (1,339 false candidates), and
removing a candidate's path from a shared corpus erased the references proving it was used.
Fixed
- The scratchpad's content was pruned and its durable artifacts promoted: 71 uncited build/runner
logs (5,529,850 B) and a stray console-output file removed, the duplicated teacher-sandbox tree
and the 4.9 MB of session transcripts relocated todev/research/— after checking every
promotion for citations, so nothing referenced was destroyed. Measured 10,544,830 B → 1,923 B. sdk/examples/readme-example-2.tsfailedeslint --max-warnings 0onmain(twoimport/order
warnings), which rejected every push through the fail-closed pre-push hook; import order fixed,
behaviour unchanged.eslint.config.jsignoresdev/research/**alongsidedev/scratchpad/**— the promoted one-off
probes and session analyses are the same class of local, untracked ad-hoc tooling.
Reclaimed
- 302,209,052 B of stale dev debug output removed — root
debug/(86,609,790 B),cli/debug/
(212,636,135 B) anddesktop/debug/(2,799,127 B), the three directories left by running the CLI
from three different project roots. All gitignored runtime state, so nothing tracked was touched.
This was step 5 of the audit and it was not executed when the record was first closed: the
closure gate verified the nine declared gates (all green) but never checked step statuses against
the filesystem, so the record claimed "all nine steps implemented" with step 5 unrun. A
post-closure check found the directories still present, the step was performed, and the premature
closure is recorded in the FID rather than quietly corrected. The.1generations found in
cli/debug/are live evidence that the new rotation fired inside a real CLI run, independent of
the unit tests.
Push sequence
This change and its governance commits were held briefly by the pre-push test gate, then pushed
once the cause was fixed — see the FID-2026-1016-012 entry above, which is the resolution of the
blocker described here as it stood at the time. --no-verify was not used at any point: the
credential scan, agent-attribution scan, ESLint, markdownlint, typecheck, the full test chain and
prettier all ran on the pushed range and passed.
Known issues (audit findings, deliberately unresolved)
dev/ is untracked by design (operator ruling 2026-10-16), so the audit's FID record is local-only
and the unresolved findings are restated here for anyone reading only the repository:
Superseded by FID-2026-1016-013 (2026-10-16) — the operator ruled on each item in this list;
the resolutions are recorded above. Kept here as the audit's own record of what it found.
desktop/public/floor-assets/robots/RobotExpressive.glbis byte-identical torobot.glbin
the same directory (463,988 B, verified bymd5sum), whileASSET-MANIFEST.mdattributes them to
different upstreams — Quaternius and the Khronos glTF sample models. Both are referenced
(desktop/src/floor/office/robot-cast.ts:39-40) and both are CC0, so there is no licence exposure;
the manifest attribution is what is wrong. Either correct the attribution or drop the duplicate
from the cast. No file was changed. → resolved: the duplicate was dropped and the false
Quaternius attribution removed;robot.glbwas the copy.coding-standards/*.mdand.agents/skills/coding-*/SKILL.mdhave diverged into two sources of
truth for the same standards. After normalising line endings the bodies differ by 18 substantive
lines (TypeScript), and the difference is not cosmetic:coding-standards/typescript.mddeclares
amax_file_lines400 /max_function_lines60 TypeScript override, while
protocol.config.yaml:51-55sets 300/50 and calls that the "LIVE quality policy — the quality
report enforces the 300-line absolute ceiling".ECHO.md:156says a language override wins, so
one of the two documents would relax a live gate.ECHO.mdstill points at
coding-standards/{language}.mdin 8 places, andcoding-standards/x402.mdexists although the
changelog records its deletion (FID-2026-0717-003). Choosing the canonical copy is a governance
decision, so nothing was edited. → resolved: one tracked ceiling of 400, no override mechanism
claimed anywhere, both enforcement sites aligned and pinned by test.WINDOWS.mdhas zero inbound references outside this changelog. It reads as real product
documentation, so deleting it needs an operator decision rather than a hygiene pass. → resolved:
verified against the source, one stale message fixed, linked from the README.- The orphan sweep reports 46 candidate files among 4,940 tracked. Six were spot-checked against
git grep; the remainder are unverified by design, which is why the sweep is advisory and exits 0.
→ resolved: two more reference-spelling defects fixed, every candidate triaged, 19 deleted and 17
retained with a stated reason; the sweep now recurs at session end.
2026-10-16 — Advertised offer deadlines are read from the feed, and the offer dump is bounded (FID-2026-1016-010, medium)
Changed
- FID-2026-1016-010 (medium): the free-options discovery surface reported a deadline it had
already parsed as unknown. Every CLI consumer of an offer deadline — the display label, the
72 h "ending soon" window and the offer-expiry inbox facts — readexpiryTimestamp, a
vestigial ISO branch written against an earlier feed shape, while the live feed emits a human
date intoexpiryDate. Measured read-only against the machine's own cached feed (219 offers,
no fetch): 0 offers carry an ISO timestamp, 12 carry a parsed date, all 219 display lines
read "deadline unverified", and the window count was structurally 0 — so no expiry fact could
ever be created and the list was uncountable for the operator. One shared
resolveOfferDeadlineMsnow prefers the ISO instant and otherwise resolves a date-only
deadline to END OF DAY UTC, so an offer is never called expired on its own advertised day;
the label, the window and the inbox facts all consume it, and the registry-host map the
refresh loop built inline (and the display discarded) is now one shared helper. After the
repair the same feed reports 12 resolved deadlines, 1 inside the 72 h window, and a label
histogram of 207 "no advertised deadline" / 12 "advertised deadline" / 0 "deadline
unverified". - The offer category lifted from the FIRST em-dash in the description, so multi-dash prose
filed run-ons such asnot an ongoing free tier — Codingas the category — which the harvest
leg's/api provider/iclass filter then read. The tail now lifts its final dash segment, and
the parser keeps the tail's ownexpiresstatement even when its date does not resolve, so a
consumer that cannot read a deadline says "unverified" instead of "no deadline". Review
against live data caught the inverse defect in the first draft of that label: keying on the
word "expire" anywhere in the prose relabelled 18 offers whose tail saysongoing— several
reading "credits never expire" — as unknown, and the shipped rule reads the tail's statement
instead. Both corrections came from measuring the real feed, not the plan's census. - The display printed every offer as one flat, unattributed line — 219 of
free-options.md's
339 lines — with no bound, grouping or attribution even thoughmatchOfferHostsattribution
was already computed for the facts and thrown away. Offer rows are now structured (title,
category, deadline label, registry labels, url) and attributed through that same matcher: the
/provider freeoutput lists the attributed offers bounded to 10 with a remainder count and
one per-category count line,free-options.mdkeeps every offer grouped by category with
counts and known-provider marks, and the boot announce previews titles. The catalog delta the
envelope already lifted (newModelIds) now reaches both headers, omitted when empty. The
presentation lives in a newcli/src/utils/free-options-offers.tsbecause the renderer was
already against the repository's 300-line ceiling — and the gate refused the work twice more
before it passed:qualityfailed two suites at 367 and 309 lines, and both were repaired by
decomposition (the display pins moved tofree-options-offers.test.ts, the pre-existing
attribution pins tocustats-attribution.test.ts) rather than by exemption. New suite
cli/src/utils/__tests__/provider-offers.test.ts(10 cases); 10/10 declared gates stamped.
2026-10-16 — Implemented candidates retire, and the exposure instrument is armed (FID-2026-1016-009, medium)
Changed
- FID-2026-1016-009 (medium): a learning-pipeline review found the lesson-feature register
had no terminal state, so seven implemented candidates — every one carrying a closed FID
and a recorded commit — sat in the active queue while the only two open drafts were buried
among them.bun run validate:repositorywas green throughout: admission validates a
candidate's evidence, and forimplementedits rules require exactly the closed FID and
commit a finished record already has, so nothing ever asked whether the work was still
open. Implemented candidates now retire verbatim todev/feature-pipeline/implemented.json;
admission fails an active entry whose state isimplemented(naming the archive), an
archived entry that is not implemented, and an identity collision between the two files.
The archive is read for the lesson-to-feature mapping and is part of the report
fingerprint, so retirement still suppresses a duplicate proposal rather than re-opening
the class LF-006 exists to prevent. The admissions pass moved to
scripts/lesson-feature-admission.tsand the archive toscripts/lesson-feature-archive.ts
after the repository's own 300-line ceiling refused the first attempt — the validator
caught two files at 338 and 350 lines and both were repaired by decomposition, not
exemption. New suitescripts/__tests__/lesson-feature-archive.test.ts(6 cases). - The same review found
dev/experiences/fix-boundaries.jsonempty, which was not a cosmetic
gap: the declaredexposure-capturehook has a documented fast path — with the manifest
empty it returns "without a write and without spawning anything" — so the sink had never
stamped a receipt andOBS-001had no instrument for the production observation it owes.
Four boundaries are now declared, each pinned to a repair commit verified to exist, to be
an ancestor of HEAD, and to contain that class's fix:run_terminal_command:timeout
(63d08c34),read_files:read-incompleteandrun_readonly_command:command-exit
(5b994ca0), andweb_search:research-unavailable(f591e40f). The other four OBS-001
classes stay unarmed with the reason recorded —read_url:http-404andread_url:http-403
are truthful upstream outcomes that the incident review forbids relabeling or bypassing,
andread_url:fetch-unextractableandspawn_agents:incomplete-argumentshave no commit
that can be pinned to their repair. The census reads the armed classes as
incomplete-observationand--assert-repaired=FID-2026-1015-006still exits 1: the
14-day, three-session window has not elapsed, and no class repair and no production
observation is claimed.
2026-10-16 — No coding-agent credit in the governed records (FID-2026-1016-008, high)
Changed
- FID-2026-1016-008 (high): the 2026-10-14 attribution rule now covers the
records agents write, not only commit messages. Commit trailers were never the
only place a coding agent got credited — a sweep found attribution fields and
watermark lines inside session summaries, archived FIDs, a build order and the
third-party channel, invisible to every gate that existed, and the new scanner
reported ten further credits in the tracked, published changelog itself. The
naming families now live inscripts/attribution-patterns.tsso both judges
read one list; the record scanner isscripts/attribution-document-guard.ts;
scripts/attribution-guard.tskeeps the commit surface, the aggregate
collector and a--documentsmode. Fenced blocks and inline code spans are
read as quotations, and Savant's own credit, a human credit, an ECHO role and
Savant's own provider id are never findings. Always on:validate:repository
aggregates both surfaces,.githooks/pre-pushscans the working tree (the
records are gitignored, so no pushed range can contain them) and the
attribution-guardworkflow gains a document step. Every credit the sweep and
the scanner found is stripped, keeping each verification claim intact.
Implementation:302ffe69, root-resolution fix04b02c0b, content strips
579e781f; four declared gates passed; closed and archived.
2026-10-16 — Batch pushed-range credential scan (FID-2026-1016-007, high)
Changed
- FID-2026-1016-007 (high): exact pushed content is now acquired in bounded
batches instead of per-path Git subprocesses. Two historical 6,207-file
delete/restore commits made the fail-closed pre-push credential scan require
roughly 24,828 launches and stall past eleven minutes with the mirror still
empty; onels-tree -r -l -zper commit plus SHA-onlycat-file --batch
reads chunked to an 8 MiB bound replace them. Range coverage, deletion
confirmation, the 2 MiB size cap and path/blob identity pins are unchanged,
and malformed, truncated, oversized, wrong-type or SHA-mismatched framing
still fails closed before any byte reaches a writer. Measured on the exact
38-commit range the push carries: 6,548 files scanned in 26 s, exit 0.
Implementation:6b2d9d91; seven declared gates passed; closed and archived.
2026-10-16 — Implementation closure and internal follow-ups
Changed
- FID-2026-1016-006 (medium): separate implementation closure from internal
observation and live comparisons. The validated local follow-up register
retains owners, provenance, next actions and evidence, appears in the agenda,
and keeps production-repair assertions strict. Repository and shipped agent
guidance close committed, code-verified FIDs immediately and automatically
push verified progress tomain; handoffs and observation windows do not
hold progress pushes. Release publication remains separate. Implementation:
dbb8de12; 10 declared gates passed; closed and archived. - FID-2026-1015-006 (high): closed and archived the committed recurrence
repairs after all 19 declared gates passed live. Windows descendant
containment, native argument diagnostics, primary-content extraction,
keyless search parsing and tool guidance are implemented. Qualified
production observation continues independently underOBS-001. - FID-2026-1012-022 (critical): closed and archived the coordination program
after all 37 children completed. Observation windows and the independent
live-comparison task (LIVE-001) no longer hold implementation closure. - Reconciled selected lessons-pipeline candidates against production code:
LF-003 (628375ff), LF-004 (d71b9065), and LF-007/008/009 (6b847099)
are implemented. Fresh focused audit: 64 tests passed, zero failed.
2026-10-16 — Remove MarsAI (FID-2026-1016-005)
Removed
- FID-2026-1016-005 (medium): removed the MarsAI built-in provider,
14-model catalog, context-window coverage, CLI setup/picker wiring and
current provider documentation. Generic custom-provider support remains
available. Historical integration records and credentials are preserved.
Registry/setup inventories now contain 47/46 providers. All 75 affected
provider tests and 11 declared gates pass; references are current.
Implementation:87c2f87a; closed and archived.
2026-10-16 — MarsAI gateway provider (FID-2026-1016-004)
- FID-2026-1016-004 (medium): added MarsAI as a built-in gateway provider —
https://marsai.click/v1,openaiprotocol,keepdispatch, credential
MARSAI_API_KEY. Static 14-id free-tier catalog from the operator's
dashboard census (console-verified; the live/v1/modelsprobe is blocked
from this network — DNS hijack + TLS reset, recorded in the FID). The
window seam carries 10 cross-gateway-sourced rows and 4 documented no-row
ids; generated and hand-maintained provider docs synced. Implementation:
62a72076; 14 declared gates passed; closed and archived.
2026-10-16 — Reconciliation closeout and repository untrack
- FID-2026-1016-001 (low): hardened the sandbox temp-workspace cleanup — the
kill path awaits a bounded child exit before removing the workspace and the
cleanup assertion compares against a run-scoped baseline. Implementation:
403262ee; 3 declared gates passed; closed and archived. - FID-2026-1016-002 (medium): identity-pinned exemptions (path + git blob id)
for the five required ripgrep binaries at all three fail-closed refusal
points; unpinned or swapped-content over-cap blobs still refuse.
Implementation:61e27b34, coverage split2e889b75; 7 declared gates
passed; closed and archived. - FID-2026-1016-003 (low):
dev/untracked from the index (1,241 paths;
files remain on disk; anchored/devignore);docs/retained per the
same-day operator ruling. Implementation:aaa83b96; 2 declared gates
passed; closed and archived. - FID-2026-1015-006 (high): re-stamped — all 19 declared gates pass live; the
record remains verified and open for the observation window (no class is
declared repaired). Repair package committed:63d08c34,0a516b26,
aa8c6a2f,f591e40f,5b994ca0; parity probe2f2d4e31; scope-targets
comment4e6247e6; runbook pointer3df0606c. - Final root test chain: 9,203 PASS / 23 SKIP / zero FAIL (9,226 ran), exit 0.
2026-10-15 — Runtime boundaries and product retirement
- FID-2026-1015-002 (medium): retired Savant-Free product paths and build
registrations; preserved ordinary model/provider routing; added scripts/tmux
to root gates, six approved skill versions and the provider reference draft.
Implementation:001e36c6; 11 declared gates passed; closed and archived. - FID-2026-1015-005 (high): reject vacuous verification, break repeated settled
checks, recover retained evidence, improve skill diffs and baseline pins,
clamp subagent writes, sanitize reports and expose pure preset stepping.
Implementation:d71b9065; 10 declared gates passed; closed and archived. - Final root test chain: 9,187 PASS / 23 SKIP / zero FAIL, exit 0. Root
typecheck, ESLint, Markdown lint, formatting, quality and SDK build passed.
Class repair remains unproved; post-cutoff findings continue under active
FID-2026-1015-006 and master FID-2026-1012-022.
2026-10-15 — Durable session save and resume with nested runtime state (FID-2026-1015-004, high)
Fixed
- Added one shared ancestor-aware, cycle-safe JSON serializer for SDK RunState
transport and database session persistence. - Preserved each caller's omission policy while replacing unexpected cyclic
back-references with a bounded, non-sensitive marker. - Added common, SDK, database, and CLI regression coverage for nested state,
repeated references, reopen-compatible reads, and user-message preservation.
Verification and archival
- Four workspace typechecks, four declared targeted suites, quality, targeted
Prettier and ESLint, root typecheck, Markdown lint, and repository ESLint pass.
The repaired full database suite passes 54/0. - Implementation commit:
628375ff. - The full root test suite passes 9,162/23 skipped/0 failed with a 10-minute
execution budget. The initial repository validation run reported the locked
clean-Linux scratch artifact plus eleven ENOENT findings from Savant-Free test
paths deleted by concurrent FID-2026-1015-002 removal work. Commitdea54d85
staged those approved deletions; the current validator reports only the
locked scratch artifact, and neither finding is caused by the declared LF-003
gates. - FID closed and archived on 2026-10-15.
2026-10-15 — clean Linux rebuild (FID-2026-1015-003, high)
Fixed
- Clean Linux tests load the shared environment defaults before workspace
isolation and use real search directories and local environment fixtures. - CLI release tests declare their tar dependency. Desktop tests compile their
native sidecar before exercising the live gateway contract. - Shared path containment rejects sibling-prefix escapes, dangling symlinks
and symlink loops. Windows path spellings normalize before Linux resolution.
Changed
- Docker pins Bun and Node images by digest, includes npm for packaging tests,
reaps child processes through tini, and provides non-secret CLI boot defaults. - Docker contexts exclude nested environment files, local credentials and backup
bundles. Runtime display paths are repository-relative. - README documents native Linux prerequisites and exact build, test and run
commands. Bun remains pinned to 1.3.14 and installs use the committed lockfile.
2026-10-15 — failure-class implementation completion
Fixed
- FID-2026-1012-017 (critical): retained the observed rejection cause through
stream settlement, later retries and exhaustion. Rejected arguments receive
schema-correction guidance; truncation retains size guidance and existing retry
limits. Six production-loop regressions pass; implementationf6224816. - FID-2026-1012-021 (high): recurring failures have explicit owners, missing
ownership fails repository validation, repair proposals are idempotent and
operator-routed, and class-repair lessons require qualified observation.
Thirteen declared machinery gates pass. - FID-2026-1012-023 (medium): validated timeout budgets, caller/executor
identity and producer-authoritative cancellation metadata survive SDK dispatch
and module-copy boundaries. Sixteen declared gates pass. - FID-2026-1012-024 (high): stable class identity, bounded result inspection,
producer-authoritative expectedness, failure capture and boundary-bound exposure
receipts are implemented. All seven historical producer mechanisms have been
investigated; seventeen instrument gates pass.
Verification and archival
Root tests: 9,206 passed / 23 skipped / zero failures. Root typecheck, ESLint,
Markdown lint, formatting, SDK build and repository validation pass. The four
implementation records close and archive on 2026-10-15 with local commit evidence.
Q25 permits named archival waivers for implementation-complete lanes; it does
not prove class repair. The capture still has 591 records / 59 stable classes /
zero ownership issues, all unresolved. Historical rows, repair boundaries and
exposure receipts remain unchanged. Each class owner retains its named waiver
and actual final implementation cutoff in dev/experiences/closure-waivers.json.
The master remains active for its registered operator/external-input holds.
2026-10-15 — Approved resume decisions (FID-2026-1015-001, medium)
Fixed
- A selected provider now owns transport and token-budget catalog identity even
when a model ID starts with another registered vendor's name. Custom endpoints
retain their own credentials; explicit model replacements retain their own route. - Session-end skill notices use an independent cursor, acknowledge after output,
preserve interactive delivery, and leave overflow or failed output unread. - Numeric task allocations persist after closure. Scope and repository validation
reject identity reuse, missing allocations, and mutation of committed history;
legacy numbers through 190 remain reserved. - Preserved local session exports byte-for-byte in an ignored archive and restored
formatting in the two approved SDK process fixtures without changing their behavior. - Registered a newly captured file-read failure with the active taxonomy owner;
no immutable capture row or production repair claim changed.
Verification
- All thirteen configured workspace suites pass: 9,120 passed, 23 skipped,
zero failures. Delivery/review/ledger suites: 23 passed. All fourteen declared
FID gates, root typecheck, ESLint, Markdown lint, formatting, quality, scope,
and repository validation pass. - SDK build succeeds. The aggregate build still fails at the existing Savant-Free
build; its operator-owned removal remains active underT122. - Implementation commits:
83f1712dandca94b6f1; final verification record:
6fe1ca49. Closed and archived 2026-10-15 after a full CHANGELOG read.
2026-10-14 — Tier 1 first-party provider parity wave (FID-2026-1012-026)
Added
- Registered the eighteen measured first-party labs — Anthropic, Google, xAI,
DeepSeek, Groq, Cohere, Together, Cerebras, DeepInfra, Perplexity, Alibaba,
Moonshot, Z.AI, MiniMax, Meta, Fireworks, Baseten and Venice — across the
provider registry, routing, setup, picker, favicon, window-coverage and
generated-documentation surfaces. - Added sixteen coding-harness-compatible static catalogs and dedicated live
catalog parsers for DeepInfra and Venice. The static source contains 288
curated chat/text rows with provider-specific window provenance; non-chat
modalities and incompatible task-only rows are not exposed by the picker. - Added the shared live-catalog filter and regression coverage so live catalogs
preserve coding-capable rows while excluding image, video, audio, embedding,
translation, OCR, ASR, TTS, safety, deep-research and multi-agent-only rows.
Changed
- The 2026-10-14
devoverriderecords keyless endpoint/catalog accessibility
as acceptance evidence. No paid inference request or provider credit was
required; keyed inference remains the user's BYOK leg. - Regenerated the provider catalog census and synchronized the hand-maintained
provider documentation surfaces. The assembled parity census now contains
3,648 runtime rows, while the curated static Tier 1 source remains 288 rows.
Verification
- Tier 1 and window-coverage suites: 10 pass / 0 fail; selected common
provider suites: 44 pass / 0 fail. bun run typecheck,providers:parity:check,window-coverage:check,
quality:report,lint:md,generate:provider-docs:check, the declared
FID gates, and the refreshed FID receipt all pass. Scoped ESLint and
Prettier checks pass;git diff --checkis clean.- FID-2026-1012-026 closed and archived 2026-10-14 at local commit
f6ce2109; no push or release was performed.
2026-10-14 — refusal authority, guard audit and agent-attribution enforcement
Fixed
- FID-2026-1014-001 (high): the read-only command guard refused legitimate
read-only work — the POSIX null sink2>/dev/nullin three spellings and
input redirection< filein two — measured 5 of 56 corpus commands, while the
EHEL mutation classifier already treated/dev/nullas a non-mutation target.
Fixed to 0. The same audit found the SEC-3 whole-segment redirect waiver live
at HEAD (2>&1forgave every other metacharacter, so the read-only tool
acceptedcat .env > /tmp/exfil.txt 2>&1), even thoughFID-2026-0919-010
closed with that fix marked DONE and a promised suite no commit ever
contained. The span-scoped strip-then-rescan is restored, the promised suite
exists, and one exported non-global predicate is shared with the mutation
classifier. 7/7 gates; corpus false positives 5 → 0; suites 18/0, 4/0, 10/0,
15/0 and 644/0 across the three affected directories. The guard's measured
under-breadth class (git push,git clean -fd,bun -e,bun x,
bun run release:public,deno eval,find . -delete,kill -9 1) is
reported and registered, pending the operator's routing ruling. - FID-2026-1014-003 (high): no coding agent may be attributed in this
repository — one rule (scripts/attribution-guard.ts), enforced by the
commit-msg hook, the pre-push commit-range scan and a CI job, and now wired
intobun run validate:repositoryso the rule travels with every clone rather
than living in layers a--no-verifybypass can skip. The two divergent copies
of the pattern list are gone; watermarks are anchored to line start (the first
whole-history run flagged the guard's own explanatory commit) and the emoji
prefix works (it was inert without theuflag). 4/4 gates; whole-history scan
exit 0; hook fail-closed on an unreadable message (exit 2). The 2026-10-02
session summary that invited footer removal "per the operator's own co-author
policy" carries a dated amendment; branch protection remains operator-owned. - FID-2026-1014-002 (medium, closed + archived 2026-10-14): registered that
a closed FID (FID-2026-0919-010) asserted an implementation and a test file
that no commit ever contained. Added the active-record declared-artifact census,
explicit absence-marker contract, and informational archive audit mode. The
active gate passes with7records,34named paths and0missing paths;
the Q24 read-only Git-history audit classified44historical missing paths
without rewriting archived FIDs. Implementation commits:1d60b9a8,
33f5c2f2; evidence and closure record:ad5c18d7. - FID-2026-1013-005 (low, closed + archived 2026-10-14): verified local
Ollama availability at HTTP 200 with three models and documented Cloudflare's
public Workers AI catalog plus its account-scoped REST credential boundary.
Q27 makes the Account ID/token an audit limitation rather than a completion
gate for the curated static catalog. No account-specific roster query or
credential use is claimed. Public-boundary commit9d6fe794; completion
evidence commite834228f.
2026-10-14 — three failure-class lanes archived under Q25
Fixed
- FID-2026-1012-018 (high): classified every
read_urloutcome, preserved
the original capture first lines, added actionable next steps, canonicalized
URL identity, and isolated negative caches per SDK run. Implementations
64ea8c06andd9cee722; 7/7 declared gates pass. Q25 records that the
recurrence window remains unproved; no repair or silence claim is made. - FID-2026-1012-019 (high): added the shared capability-degradation contract,
truthful research exhaustion and code-search flag outcomes, and run-start
capability preflight. Implementations09f0c892and3ee91a35; 10/10
declared gates pass. The named Q25 waiver preserves the unresolved observation
boundary and does not claim the host-side resolver class repaired. - FID-2026-1012-020 (medium): added bounded edit diagnosis, separated mismatch
from no-op outcomes, removed unsafe patch/error payloads, and corrected the
frozen client-result mutation path. Implementations0e7b3414andbe66e79f;
11/11 declared gates pass. Q25 archives the implementation-complete lane
without claiming qualified production observation.
FID-2026-1012-017 remains active: its four measured post-fix classes are rejected
by the recurrence gate and are not excused by the Q25 waiver.
2026-10-14 — QOL hardening program completed (five FIDs archived)
Fixed
- FID archive alignment: Backfilled fifteen missing October 13 archive-index
entries and eight existing implementation hashes in the G2 pre-audit's
canonical metadata field. Historical verification evidence remains unchanged. - FID-2026-1013-010 (high): Write-tool paths survive compaction and reach
graph evidence; Law 1 resolves against the project root; evidence shards cache
by size/mtime; micro-compaction reports actual savings and preserves tiny
results; failed structured-output diagnostics and logs redact before truncation. - FID-2026-1013-011 (medium): Shared display, truncation, coercion, render,
nameplate and SQLite primitives replace duplicated implementations, with
production consumers and registry enforcement preserving compatibility. - FID-2026-1013-012 (medium): Type-safety and lint-rationale enforcement,
scanner literal/comment handling and ceiling decompositions are complete.
Closure review replaced the quote-sensitive scanner with the pinned compiler
parser/scanner and regression controls for regex, templates, division and TSX. - FID-2026-1013-013 (medium): Desktop tool attribution, diff/output previews,
approval notes, walker lookup and cursor ownership, plus CLI collapse-timer
cleanup and shared empty-ad state are complete. - FID-2026-1013-009 (high): Coordinator closed after all four children;
all 24 allocated findings are committed inb959019e. The shared
renderer/reducer dependencies ship as one coherent program. All 52 declared
child gates, full root tests across thirteen workspaces, root typecheck,
ESLint, Markdown lint, SDK build and repository validation pass. Fresh live
TUI/WebView visual smoke is unclaimed. No push or release was performed.
2026-10-13 — The bundle restore drill gets a budget it can meet (FID-2026-1013-008)
Fixed
- The scripts suite is green on a loaded machine, not only a quiet one. Its fifth independent
failure was a clock, not an assertion:git bundle backup > restore drillmeasured 4261-5462 ms
across three isolated runs — real baseline clone plus incremental fetch through spawned git —
against bun's 5 s default, with siblings in the same file at 1.0-3.3 s. The file now declares
GIT_CHILD_TIMEOUT_MSbeside the measurements that justify it, following the convention already in
this tree (FID-2026-1010-004); assertions untouched. Implementation4be4de9e;
cd scripts && bun test960 pass / 0 fail, exit 0.
2026-10-13 — Both suite-health records close (FID-2026-1013-006/-007)
Fixed
- The scripts suite is green from its declared cwd (FID-2026-1013-006). Four independent
deterministic failures, none of them load flakes: two live-repository checks resolved the
repository root fromprocess.cwd()— which isscripts/under the FID-2026-1013-001 gate
contract — so they readscripts/CHANGELOG.md; the boundary probe rejected every cross-origin
redirect, including the apex→www hop its own re-POST logic exists for (the guard is now the
site: same scheme and port, base host, subdomain or parent, so an unrelated host still fails
closed); and two git-fixture tests that spend 4-6 s in process spawns on Windows were held to
bun's 5 s default. Implementation722d1c03; no assertion was removed or weakened. - The graph leg absorbs Windows lock codes and its own fixture cost (FID-2026-1013-007). The
refresh-safety teardown retriedEBUSYonly, for 250 ms, while Windows reportsEBUSY,EPERM,
EACCESorENOTEMPTY; the fabricated 10,001-entry enumeration test now carries a budget that
matches what it deliberately performs. Implementation2f003aed. The rootbun run testchain is
green across all 13 legs, andbun run validate:repositorypasses.
2026-10-13 - The AIHubMix gateway joins the built-in registry (FID-2026-1013-004)
Added
- AIHubMix (
aihubmix,AIHUBMIX_API_KEY) is a built-in gateway provider on
https://aihubmix.com/v1, singleopenaiprotocol andstripid transform, using the
vendor's richer keyless catalog at/api/v1/models- probed 2026-10-13: HTTP 200
with 869 rows, of which 698 carry the exact comma-delimitedllmtype token. The
wrapper filters on that token, preserves sparse-endpoint rows rather than dropping
them, and usescatalogLimitwithout fabricating any limit the vendor omits. - Window coverage is declared
runtime-partial- of the 698 LLM rows only 358
publish a positive context limit and 306 a positive output limit, so zero, missing and
non-positive values stay unknown and no fallback is invented. The exception manifest
owns thelive-catalogbehaviour and the census records the measured row count. ProviderConfig.extraHeaders- a registry-owned carrier-header field. AIHubMix's
documentedAPP-Codegrants a standing discount, and no seam existed for a
provider-specific request header (the codebase's only precedent was a provider id
hard-coded by name in two factories). The new optional field is applied on all four
generic-factory protocol branches and plumbed through theDIRECT_PROVIDERbare-slug
path, so a declared header cannot be dropped by a protocol dispatch or a routing mode.
The custom-INFERENCE_BASE_URLbranch is deliberately excluded: an operator-owned
endpoint must never receive a registry provider's identity headers.
MFSO2605is a public discount code, not a secret, so it is registry data and never
an env var.
Fixed
- Two
import/orderviolations ingateway.tsandgateway-live-results.ts, where
the new./aihubmiximport sat after./apinex, plus an over-wrapped
positional-contract comment. - A stale register entry. The archived Apixo FID's
SCOPE.mditem outlived its
closure and was evicted here.
Known limitation
- A free-model inference probe returned HTTP 200 with an account-policy apology, not a
substantive completion. This is recorded as transport and credential reachability
only; it is not an inference-acceptance claim, and a later substantive completion
would be stronger evidence rather than a correction.
2026-10-13 - The Apixo gateway joins the built-in registry (FID-2026-1013-003)
Added
- Apixo (
apixo,APIXOAI_API_KEY) is a built-in gateway provider on
https://api.apixoai.online/v1, singleopenaiprotocol,stripid transform, and
a keyless live catalog (/v1/models) — probed 2026-10-13: HTTP 200 both keyless
and keyed with byte-identical bodies, 35 rows, and one real completion on
deepseek-v4.1-flash. The/providerpicker,/modelcatalog, routing prefix,
credential readiness and favicon all derive from the registry entry; the new wrapper
carries a dedicated parser for the vendor'scontext_window/
max_output_tokensrow shape, which the shared OpenRouter-shaped parser would have
read as zero windows (the measured Vercel mis-parse class). - Window coverage is declared
runtime-published— the catalog publishes a window
on every one of its rows, so the runtime value is the source of truth and no
fallback-table section is owed. The exception manifest owns thelive-catalog
behaviour, and the live census records the measured row count.
Fixed
- Two registry-enumeration tests that the provider runbook does not name
(common/src/providers/__tests__/provider-registry.test.ts) now carryapixoin
the registry-key, setup-key and order-4 lists — a new provider fails those before
any pipeline gate sees it. - Pre-existing prettier drift in three files this change does not own
(packages/agent-runtime/src/hooks/exposure-capture.ts, its suite, and
scripts/__tests__/experiences-proof.test.ts) was repaired in the same pass so the
hard format gate is green. Formatting only; no behaviour changed.
Verification
All eleven declared gates exit 0 (receipt stamped 2026-10-13T18:01:05.201Z); full root
typecheck exit 0; every workspace suite green — cli 4155, common 871, sdk 672,
agent-runtime 2103, desktop 450, evals 229 plus six smaller workspaces, all 0 fail;
quality:report PASS; eslint, markdownlint and prettier exit 0;
generate:provider-docs:check, providers:parity --check (apixo: 35) and
window-coverage:check clean. validate:repository was not run by operator ruling
2026-10-13 (recorded verbatim in the archived FID); the sub-checks this change owns were
run individually. Closed and archived at 6c32495.
2026-10-13 — The learning-store and harness lanes close (FID-2026-1012-010/-011/-012/-013/-014/-015/-016/-027, FID-2026-1013-001/-002)
Fixed
- The lessons ledger has a size contract and its boot read is bounded
(FID-2026-1012-010, FID-2026-1012-011). The 1,200-logical-line and 100,000-character
ceilings moved from the retirement tool into the validator, solearnings:checkand
thereforevalidate:repositoryfail on either breach and report headroom while green;
retirement emits a machine-readable move record and now recovers from an interruption
mid-move. The boot read is a generated 24,000-character rule digest, and grounding credit
is refused for windowed, truncated or status-only reads. - Retirement no longer strands by-title references, and lesson evidence stops rotting
(FID-2026-1012-012, FID-2026-1012-013). One locator spans the live ledger and the retired
archive and resolves supersession with replacement notices; the seven admission issues that
leftlessons:features --checkred are resolved. Reproduction references are structured,
ephemeral roots are rejected, and historical pins must validate their actual commit and blob. - The rule catalogue and the ledger are kept in step (FID-2026-1012-014, FID-2026-1012-016).
Every catalogue rule carries a tier and a reason, every non-historical lesson names exactly
one catalogue rule, and the shipped subset is a deterministic projection of the boot tier.
The consolidation inventory is exact-merge only: 74 unique titles, zero eligible proposals,
zero mutation, zero boot saving claimed. - The lesson-to-feature pipeline is gated by its own independent collector
(FID-2026-1012-015);lessons:features --checkpasses over the reconciled store and its
report fingerprints the live, retired and manifest inputs, publishing deterministic red
reports instead of a stale green one. - Coverage of a fixed record's own surface is now a checked relation
(FID-2026-1012-027).scripts/fid-surface-coverage.tsjoins each enforced record's declared
gates to itsSCOPE.mdwrite surface; it found and repaired two real omissions and
fid:verify --writerefuses an uncovered stamp first. - Script test gates resolve from the
scriptsroot (FID-2026-1013-001), so receipt
execution no longer runs repository-root substring discovery over script suites. - Partial assertions no longer mutate the evidence they check (FID-2026-1013-002).
Three inlinetoMatchObjectcalls replaced received fields with matcher objects under
Bun 1.3.14; they now use a non-mutating equality/partial-object composition, with a shared
AST collector wired into repository validation. - All ten records re-ran their declared gates green on the closure tree (13+6+8+7+12+5+5+6+3+10
= 75 gate executions, every one exit 0), then were closed and archived at their
implementation commits. FID-2026-1012-011's recovery commit isca1f359d. The failure-class
remediation master (FID-2026-1012-022) remains active: its class lanes still await
exposure-qualified observation.
2026-10-12 — Verification harness drift repaired (FID-2026-1012-025)
Fixed
- Wire the existing model-picker and compliance-capture resets into their workspace
test preloads. Preserve the operator-approved Tauri allowlist with positive and
forbidden-command controls, and point the window-census test at the loader's durable
measured fixture rather than a removed scratchpad file. - Standalone provider probes now run only through guarded entrypoints. Import-safety
tests first reproduced attempted requests with a fetch blocker, then pass without
requests or credential reads. Both programs share a typed credential reader. - Closed and archived at implementation
c4018491fcf0ff7183c009d9bf5b559c84dc329f.
Ten declared gates pass; full root typecheck, lint and quality pass. Sequential broad
suites: scripts 451 PASS, agent-runtime 2,037 PASS. No timeout budget was raised.
The failure-class remediation master remains active; this closes its harness finding.
2026-10-12 — Truncated tool calls are steered to split the payload (FID-2026-1012-009)
Fixed
- A payload cut by the output budget was answered with a re-send that
truncates identically (FID-2026-1012-009). The output-cap discriminator
FID-2026-0909-008 built —finishReason === 'length'selecting "split the
work into smaller calls" — was unreachable from the path that actually
produces these failures:classifyInvalidToolCall(the vendor-SDK
transformer foranthropic,googleand the rest) receivedaicore's
invalid: truetool-call part and rebuilt the error by hand as
{ type: 'native-incomplete', toolName }. The stream'sfinishpart arrives
after that classification, so no finish reason exists there to branch on. Every
one of the 48read_filesnative-incomplete failures recorded between
2026-10-02 and 2026-10-12 carried the generic "retry the tool call with a
complete arguments object" text and none the cap text — advice that cannot
work on arguments the model never finished writing. - The vendor path now carries the discriminator it alone holds.
aicore
already separates the two cases:safeParseJSONreturns aJSONParseError
when the arguments never parsed (the document did not close, i.e. the payload
was cut) and aTypeValidationErrorwhen they parsed but missed the tool's
schema, anddoParseToolCallattaches that result as the
InvalidToolInputError'scause.isTruncatedToolInputreads it, and
classifyInvalidToolCallmarks the errorargumentsTruncated. Schema/type
failures, a missing cause and unrecognised shapes stay on the generic retry
text, so the fail-closed default is unchanged and no execution path, argument
rewrite or strike budget was touched. Message and ladder selection only.
Added
NativeToolCallErrorand the native-incompleteStreamErrorChunkcarry an
optionalargumentsTruncated?: boolean, withisNativeToolCallError
rejecting a non-boolean value — the same hostile-shape discipline its
finishReasonfield already had. Both truncation causes (a provider's
output-cap finish reason, and a parse failure the classifier observed itself)
select one shared advice sentence with a truthful cause clause per case
(Law 13), so the wording cannot drift apart between them.
Verification
sdk/src/impl/__tests__/llm-native-tool-call.test.ts12 pass / 0 fail (five
new cases: a parse-failure cause selects the split advice; a schema failure
and a missing cause keep the generic text; a false flag keeps the generic
text; a hostile non-boolean flag is rejected by the guard).packages/agent-runtime/src/tools/stream-parser/__tests__/error-chunk-steering.test.ts
10 pass / 0 fail, including a new pin that the truncated body survives the
runtime and still gains theread_filesstrike-1 steering.- Root
bun run typecheck(13 workspaces +scripts/), ESLint--max-warnings 0
over the changed files, Markdown lint,quality:reportand the record's five
declared gates all exit 0. Implementation:682399fd. - Boundary recorded rather than claimed: the classification and both message
selections are proven at unit level. The eight-day ledger stores only each
error's first line, so it cannot retro-attribute its 48 records to cause; the
next occurrences must be read fromdev/experiences/raw-traces.jsonlto
confirm the class text changes, and the capture-sideerrorClass/truncation
field remains open as a follow-up.
2026-10-12 — Researcher acceptance and the lesson feature pipeline closed (FID-2026-1012-003, FID-2026-1012-004)
Changed
- FID-2026-1012-004 (
verified→closed) on the operator's directive. The
feature pipeline itself is unchanged and stays verified: 74 headed lessons
(55 schema-governed), six reviewed candidates, the read-only report/check
command with its explicit write mode, and bounded routing notes on the
production SessionEnd hook. Closing also landed its own output — see the
section above for the two implemented candidates. - FID-2026-1012-003 (
verified→closed): the researcher-acceptance and
render-recovery repairs (MCP schema preservation, typed argument recovery,
the shared traffic-light panel for namespaced tools, rich-text normalization
and per-group transcript containment) close on their eight declared gates,
all exit 0 at the archived path. Two boundaries are recorded rather than
claimed: the exact original offending subtree was never logged, so the repair
is pinned by the shapes it covers, and the operator's original prompt still
needs their live acceptance on the repaired build. - The cited build blocker was measured rather than restated: the aggregate
bun run cired is the FID-2026-0805-002 integrity gate refusing this
machine's repo.env.local(devNEXT_PUBLIC_SAVANT_CODE_APP_URL), and the
Savant-Free leg builds green under the documented clean-shell condition
(SAVANT_FREE_MODE=true bun --no-env-file cli/scripts/build-binary.ts savant-free 0.0.0-dev
→ exit 0). T122 remains an open, operator-owned item — repair the
Savant-Free feature or remove it; nothing in this pass resolves it. SCOPE.mddrops the two closed items and their machine-readable targets, as
the register's own rule requires.
2026-10-12 — read_files windows and child-agent context propagation (FID-2026-1012-007, FID-2026-1012-008)
Added
common/src/util/read-window.ts— one newline-exact line-window extractor
shared by the SDK's read boundary and the runtime handler. A window that ends
before EOF keeps its separator, so consecutive pages of a large file
concatenate back to the original content byte-for-byte (asserted with a
matching SHA-256 over a >100k-character file).RequestFilesFn(common/src/types/contracts/client.ts) accepts an optional
offset/limitwindow, forwarded by
packages/agent-runtime/src/get-file-reading-updates.tsand served by
sdk/src/run/tool-call.ts→sdk/src/tools/read-files.ts. An
overrideTools.read_filesimplementation receives the window in its input and
owns its response.resolveChildContextWindow(spawn-agent-utils.ts) — the model-route guard
that propagates the run's resolved context window to a child agent running
the same model, mirroringresolveChildOutputBudget.
Changed
subagentContextParamsnow carries the run'scompressionpolicy into every
child agent. The policy is model-independent, so a pinned-model child inherits
it too; the model-scoped window is deliberately kept out of the extractor and
travels through the guard instead.- Embedded grounding reads are windowed locally by the
read_fileshandler; the
handler no longer slices a filesystem response, because re-slicing an
already-windowed response silently drops lines. sdk/src/run/require-cwd.ts—requireCwdmoved verbatim out of
tool-call.tsto keep the dispatcher under the 300-line absolute maximum.
Fixed
read_filesreturned nothing for a window past the read cap
(FID-2026-1012-007).offset/limitwere applied after the SDK truncated a
file atREAD_FILES_MAX_CHARS, so the tool's documented large-file escape
hatch was unreachable:dev/LEARNINGS.mdhas 2,147 lines, its capped prefix
holds 1,552, andoffset: 1750came back empty while the lines were on disk.
The window is now served from the complete content at the fetch boundary and
the response is still capped; traversal, ignored-file and 10MB rules are
re-pinned for windowed reads. Commits303c6838,e3bea01e.- Child agents compacted by default and sized thresholds from a fallback
(FID-2026-1012-008). The spawn boundary's field whitelist dropped the run's
compressionconfiguration and resolvedcontextWindow, so a child built its
ContextCompactorfromundefined: micro-compaction defaulted ON
(microCompactEnabled ?? true) while the run had it off — clearing fetched
research records mid-synthesis at 11% of the threshold — and the window fell
back to 200,000 regardless of the model. Both now reach the child through the
routes their scoping demands. Commits7fbecd99,e3bea01e.
2026-10-12 — Managed temporary scratchpad (FID-2026-1012-006)
Added
dev/scratchpadis now managed temporary storage rather than an unmanaged
drawer. A native lifecycle manager incommonexpires idle files after 24
hours and prunes above 32 MiB / 1,000 files with a one-hour grace, never
follows links, never removes anything outside the scratch root, and preserves
the rootREADME/.gitkeep./scratchpad statusand/scratchpad cleangive the operator the same
policy in the CLI;cleanis not a force-delete command. Both variants get
the command because it ridesCORE_SLASH_COMMANDS.- Live native runs hold a whole-root lease, so an executing agent never loses
its own temporary files (including terminal-created flat files the sweep
never scanned). Dead owners are reclaimable, a reused PID conservatively
protects, and malformed coordination data blocks deletion with an explicit
diagnostic instead of guessing. Injected filesystems never trigger host
housekeeping, and housekeeping failures warn rather than crash a run. - The sweep runs at CLI startup, every five minutes while idle, and
before/after native SDK runs, releasing protection on success, failure and
cancellation.
Changed
scripts/hygiene.tsnow reports only root-level scratchpad clutter; expiring
nested files is the runtime manager's job, not the lint's.- Agent instructions and
docs/scratchpad.mdstate that scratch is temporary
including the legacy archive directory — "age archive into another
archive" does not bound growth — and name the durable homes for reports
(dev/test-prompts/archive/,dev/session-summaries/) and reusable probes
(scripts/providers/audit-probes/).
Fixed
- The probe that moved out of the gitignored scratchpad into the typechecked
scriptstree had no module marker, so its top-levelawait(TS1375) broke
the scripts typecheck — which also failed FID-2026-1012-004's declared
scripts-typecheck-checkgate. The marker and the probe's stale
run-path documentation are both corrected.
2026-10-12 — Tiarina Cloud is a built-in gateway (FID-2026-1012-005)
Added
tiarina(Tiarina Cloud,https://ai.tiarina.cloud/v1,TIARINA_API_KEY)
is registered as a hosted gateway: it appears in/provider, routes
tiarina/<model-id>, and shows up in the generated.env.exampleblock,
README.md,cli/release/README.mdanddocs/providers.mdregistry table.
No adapter and no SDK change — the request router is registry-driven, which
the new keyed round-trip through the production chain proves end to end.- The catalog is the checked-in 19-id allowlist the keyed
/v1/modelsprobe
returned rather than a live fetch — the same call the repo made for
ChatAnywhere, for the same measured reason: not one of those 19 rows publishes
a context window, so a live catalog would still need the identical
fallback-table section. The suffixed:freeand:cloudflareids are rowed as
the separate roster entries they are. - Window coverage: a new
context-window-table-tiarinaseam carries 18 rows,
each read off existing cross-gateway rows for the same upstream model (two of
them pinned at the conservative minimum of two disagreeing >=2-row groups),
plus one documented no-row id that keeps the flagged 200k default.
NO_PUBLISH_GATEWAY_IDSmembership is what mechanically enforces the seam
file and its window-truth suite. - The provider's own tests:
fid-2026-1012-005-tiarina.test.ts(windows compared
against an independent oracle, never against the table the builder reads) and
window-truth-tiarina.test.ts(roster windows, variant inheritance, total
19-id coverage, seam-wiring census). The suite also asserts what this shape
does NOT have: zero exception-manifest entries.
Changed
- The closed-world registry pins widened from twenty-six providers to
twenty-seven (twenty-five setup providers to twenty-six). provider-catalog-census.jsonwas regenerated withproviders:parity— the
committed copy was a stale 2026-10-06 subset, so the file now carries the full
current assembly includingtiarina: 19.
Fixed
docs/adding-a-provider.md's live-catalog example resolved its key with
process.env.MYPROVIDER_API_KEY, while every shipped wrapper calls
resolveProviderApiKey(providerId)— the seam that also sees a key entered
through/provider. Following the runbook literally produced a catalog that
401s for every wizard-configured user.- Still open for the operator:
.env.example:152cites taskT146, which is not
registered (the register carries that work asT147); every.env*surface is
operator-owned underno-write-dotenv, so the one-character fix is left to them.
2026-10-12 — Scholarly research through the public Scholars Reading List MCP service (FID-2026-1012-001)
Added
- Medium-severity capability gap resolved:
researcher-webconnects to the
public, keyless Scholars Reading List MCP service for paper search, record
lookup, similarity search, and shared-reference citation traversal. The native
web tools remain available when the literature service cannot be loaded. - Definition and runtime regression coverage pins the remote HTTP contract,
all four model-visible MCP tools, and native-tool fallback on server failure.
The bundled agent is regenerated from its definition.
Fixed
- Literature questions follow MCP-first research and verify citations against
fetched paper records; the old unconditional web-search and three-page rules
now apply to web research. Paper claims beyond abstracts require full-text
verification. Parameter guidance follows the live MCP schema: string-valued
abstracts, resultlimit, and citationbreadth. - Researcher capability summaries now include scholarly literature. Completion
review verifies the committed implementation and live tool round trips,
records the verification receipt, and closes the FID with archive/register cleanup. - Remote HTTP/SSE MCP calls now carry network effects with prompt permission;
the executor admits discovered tools offered by the current step from the
agent's own configured servers. Unowned, unoffered and safe-mode calls stay
blocked; stdio tools retain mixed effects. Error recovery checks the actual
offered tool set, including MCP tools, rather than only the native name list.
2026-10-12 — Unavailable-tool calls are no longer misdiagnosed as argument truncation (FID-2026-1012-002)
Fixed
- The OpenAI-compatible stream transform answered two questions with one predicate:
isCompleteKnownToolCallArgumentsreturnedfalsefor a tool name the request never declared
before it looked at the arguments, so a call with perfectly well-formed JSON was emitted as
native-incompleteand the model was told to send a complete argument object — a remedy no retry can
satisfy. The vendor path lost the same distinction one layer later, whereclassifyInvalidToolCall
read only the tool name and discarded theai-coreNoSuchToolErrorthat said otherwise. A new
tool-unavailableclass now carries the name-only failure end to end, with its own honest message
and a one-retry budget (TOOL_UNAVAILABLE_RECOVERY_MAX_STRIKES = 2; the counter includes the current
step) instead of the truncation ladder's three strikes. - A tool-restricted subagent was also invited to call tools it does not have: the subagent addendum's
phase-gating sentence namedrun_readonly_commandandread_files/glob/list_directory/
code_searchas "available in ALL phases" inside a message whose first sentence said the opposite.
The note is now derived from the child's own allowlist, and the allowlist-blind drift check in
packages/agent-runtime/src/tools/stream-parser/error-chunk.tscompares against the agent's tools,
so the class is visible in logs and the ledger instead of silent. - Protocol markup reaching the user as prose: the parser recognized only the canonical envelope and one
legacy name, so an observed<SAVANT_TOOL_CALL>block — a name that has never existed in this
repository's history — was passed through with itscb_tool_nameJSON intact. Known aliases and case
variants now normalize to the canonical envelope, and any other tool-call-shaped envelope is
discarded rather than rendered. - The reported run died at
loop-iteration.tsnaming aread_filespayload problem for an agent whose
tool list issequentialthinking/end_turn. The RED-first probe
(dev/scratchpad/active/fid-1012-002-unavailable-tool-probe.ts) failed with four named issues before
the change and passes now; three pre-existing suite fixtures that called tools their template never
declared were corrected to declare them, since the truncation ladder they pin applies only to a tool
the agent actually has.
2026-10-12 — System review: twenty findings repaired and verified (FID-2026-1011-006)
Fixed
- Knowledge graph: the default parser read relative to the process cwd, so a project
outside it silently lost symbol/CALLS evidence; directed reachability rebuilt path order
by position from rows that carry no such contract; blast-radius traversal enumerated
simple paths, re-exploring every alternate route and blocking its caller synchronously
(166-173 ms at nine nodes on an adversarial dense fixture); cluster counts reported file
anchors as node counts; a same-content mtime change never advanced the stat baseline; an
unchanged refresh still rebuilt edges and clusters; the edge clear committed outside the
replacement transaction; and an incomplete enumeration was treated as proof of deletion.
Repairs are per-vertex bounded traversal, a completeness certificate on the tree scan, and
one whole-refresh transaction that verifies its baseline before writing. - Parser: the output caps were applied after the work — twelve files were read to return
one — and an oversized file was read to completion before its size was checked. Admission
now precedes every read and counts UTF-8 bytes. - SDK/runtime: a handler rejection bypassed settlement cleanup, so snapshots kept running
after the host had a rejected run; the retry and recovery wrappers drove their sources
without closing the owned iterators. - Connectors: live invocation ignored its fetch override (the injected function saw zero
calls while the global one ran), and the bundle cache keyed on nothing and retained a
rejected load. - Desktop: a superseded socket's callbacks could close the current connection and reject its
requests, and a transport firing its handlers synchronously hit an unassigned socket. - Persistence: a stable message id kept its first content forever; a failed steering-audit
write was dropped while the code documented a retry; every label row counted as a
completed compaction boundary; a throwing commit observer turned an already-committed
write into a reported failure; and the persisted import resolver could escape the project
root. - Catalogs: a reset could be overwritten by an earlier in-flight fetch, and a credential
rotation was served from a cache assembled with the previous key.
Added
- Regression suites at each repaired seam (
refresh-safety,edges-from-tokens,
gateway-client-generation,session-entry-persistence,live-catalog-generation) and
the FID's declared gate set: 36 gates, all passing, with the verification receipt stamped. invalidateGatewayCatalog()drops the merged catalog, the in-flight slot, the on-disk
warm-start snapshot and every per-provider cache when a credential changes, wired to both
provider-key save paths;activateProviderRoutingmoved to its own module at the quality
ceiling.
2026-10-11 — cli-bundle-resolution runs against a pristine install (FID-2026-1011-005)
Fixed
cli-bundle-resolutionbundled the CLI in the working tree, sobun buildresolved
imports against whatevernode_modulesthe machine had. Measured on this machine: an
import no manifest declares and no lockfile install provides — present only in a stray
C:\Users\spenc\node_modules— let the gate exit 0, the same mechanism that supplied
ajv/dist/2020.jsat v0.0.35. The gate now materializes the release file set into a
scratch tree, installs the frozen lockfile there, runs the release build's own prebundle
steps, and fails when any module the bundler loaded resolved outside that tree (or when
the module graph records nothing). Cost: ~1m49s, in the release battery only — the
pre-push hook does not run the gate contract.- The root gate contract now invokes the probe (
bun run scripts/cli-bundle-resolution-check.ts), the engine's rules are pinned by
scripts/__tests__/clean-install-bundle.test.ts(15 tests), and the operator can run it
by hand asbun run bundle:resolution.
2026-10-11 — Release gate for undeclared imports (T188, FID-2026-1011-004)
Added
undeclared-imports— a release gate that grades every tracked-source import against
the repository's own declarations and NOT against the installed tree, so a mutated or
stalenode_modulescan no longer make it pass. That is the class
cli-bundle-resolutioncannot see: at v0.0.35 that gate ran green locally on a leftover
ajv v8dist/tree while CI, resolving the committed lockfile, failed on the same
import.scripts/undeclared-imports.ts(pure detector) and
scripts/undeclared-imports-audit.ts(collector + probe) read onlygit ls-files, the
26 manifests andbun.lock.transitive(no manifest declares it; only a transitive
dependency hoists it — the v0.0.35ajv) andabsent(not even in the lockfile — the
v0.0.24@noble/hashes) fail; cross-workspace and root-declared imports resolve and are
not reported.
Fixed
- The audit found four packages that no manifest declared. Declared them:
picocolorsin
cli(four files undercli/srcare bundled into the shipped binary and nothing owned
the dependency — it arrived only throughpino),picocolorsandjs-yamlin
scripts/tmux, andglobals,playwrightandplaywright-coreat the root (the eslint
config, the HUD browser check, and the desktop browser-smoke fixtures), then regenerated
bun.lock. cli/release-core/launcher.js: a failed background update is now reported instead of
swallowed. v0.0.35 published to npm while its release assets were missing, so the
launcher resolved the new version, failed the download, and said nothing — every
existing install kept running its stale binary with no signal. Still non-fatal: the
session starts normally.
2026-10-11 — v0.0.35 shipped without binaries: phantom ajv in connectors (FID-2026-1011-003)
Fixed
- Restored the five missing binary assets on the
v0.0.35GitHub release, which had
shipped empty and left every existing install silently unable to auto-update. packages/connectorsimportedajv/dist/2020.jsandajv-formatswithout declaring
either, so they resolved only from a rootnode_modules/ajvholding ajv 6.15.0 plus
stale ajv v8 files from an earlier install. Every local release gate ran green while
all five CIBuild binaryjobs failed after npm had published. Declaredajv ^8.17.1,
ajv-formats ^3.0.1, and — found by this FID's own import sweep —@savant-code/common
(workspace:*), then regeneratedbun.lock(ajv hoists to 8.20.0 and eslint's ajv 6
nests undereslint/*). Backfilled the tarballs frommain(4d2369bd, workflow run
38184652261) with no version bump, perdocs/public-release.md.- The install-independent guard for this class is registered as T188, blocked on the
operator ruling for the release gate battery (T186 precedent).
2026-10-11 — Public release validation excludes the unpublished SDK (FID-2026-1011-002)
Changed
- Scoped public release build, typecheck, test, and committed-head validation
to the CLI release and its repository dependencies. The default release
publishes onlysavant-code, but validation ran the SDK build, typecheck,
and test chain — so an unpublished workspace could fail the release gate.
Addedbuild:release,typecheck:release, andtest:releaseto
package.json(12 workspace legs each;build:sdkfiltered at
scripts/validation-gates.ts:276, root chains swapped for the release
chains at:279,282). The full root workspace gates remain available for
development and CI and are unchanged — release coverage is exactly root
coverage minus thesdkleg, omitting the samesavant-free, scripts/tmux
pair as the root chains (T186). Verified:fid:verify --check3/3 PASS
against the final archived bytes, the recomputed fingerprint matching the
storedsha256:22f98686…at closure entry, and the focused suites at
21 pass / 0 fail.
Truncated to GitHub's 125000-character release-body limit; the complete section (126098 characters) is in CHANGELOG.md.