Skip to content

fix(#51): clone config defaults, null-unset route overrides, resettable session, telemetry on every command - #126

Merged
bigknoxy merged 1 commit into
mainfrom
fix/51-longtail-correctness
Aug 19, 2026
Merged

fix(#51): clone config defaults, null-unset route overrides, resettable session, telemetry on every command#126
bigknoxy merged 1 commit into
mainfrom
fix/51-longtail-correctness

Conversation

@bigknoxy

Copy link
Copy Markdown
Owner

Closes #51.

Four real defects from the long-tail sweep; three of the seven items in the issue (3, 4, 5) were already fixed by #40 and #105 and are covered by existing tests.

1. loadConfig aliased the default telemetry object

A shallow spread of the frozen DEFAULT_CONFIG left the nested telemetry object shared. One caller mutating its own config silently rewrote the defaults for the rest of the process. Invisible in the CLI (one process, one call); a cross-request leak in the MCP server and any library embedding. cloneDefaults() deep-clones.

2. Route-policy overrides could not be unset

A higher-priority config could add or change an override but never remove one, so a global "always diff for Python" policy could not be opted out of per project. The override maps are now Record<string, EditRoute | null>; mergeOverrides treats an explicit null as "unset", and policyForce coerces null to undefined.

3. Telemetry session id was fixed for process lifetime

A module-level const meant a long-lived host reported every event under one session forever. newSession() and setSessionId(id) added and re-exported from the barrel.

4. Roughly half the CLI commands emitted no telemetry event

Health reports therefore undercounted usage. Rather than thread recordEvent through ~20 actions with several finish() sites each, the fallback event is emitted inside finish() itself — the single choke point every command funnels through — gated on getRecordedEventCount() === 0 so richer per-command events are never double-counted. telemetry * and uninstall are exempt: recording there would grow the very log being inspected, or outlive the directory being removed. (Commander postAction hooks were considered and rejected: the CLI uses sync program.parse() with async actions.)

Verification

  • tests/longtail-51.test.ts — 10 tests. Items 1 and 2 run as a child-process probe under an isolated HOME, because a real global config on the dev machine rebuilds the nested object and masks the aliasing. Item 4 enumerates commands in child processes and asserts exactly one event each with elapsed_ms > 0, plus a test that telemetry summary writes nothing.
  • Falsification: stashing src/core/config.ts → 3 failures (items 1, 2); stashing src/core/exit-codes.ts → 2 failures (item 4).
  • Full suite 866 pass / 0 fail across 42 files; bun run lint:docs clean; no scratch leftovers.
  • No bench case: these are config and telemetry defects, outside the bench harness's edit-correctness model.

🤖 Generated with Claude Code

…le session, telemetry on every command

Four long-tail correctness defects from the #51 sweep:

1. `loadConfig` shallow-spread the frozen defaults, leaving the nested
   `telemetry` object aliased. One caller mutating its own config rewrote
   the defaults for the rest of the process — invisible in a one-shot CLI
   run, a cross-request leak in the MCP server and any library embedding.
   `cloneDefaults()` now deep-clones.

2. Route-policy override maps could add or change an entry but never
   remove one, so a global "always diff for Python" policy could not be
   opted out of per project. The maps are now
   `Record<string, EditRoute | null>` and `mergeOverrides` treats an
   explicit `null` as "unset".

3. The telemetry session id was a module-level `const`, so a long-lived
   host (MCP server, library embedding) reported every event under one
   session forever. Added `newSession()` and `setSessionId()`, both
   re-exported from the barrel.

4. Roughly half the CLI commands recorded no telemetry event at all, so
   health reports undercounted usage. `finish()` — the single choke point
   every command funnels through — now emits a fallback event when the
   action recorded none, gated on `getRecordedEventCount() === 0` so a
   richer per-command event is never double-counted. `telemetry *` and
   `uninstall` are exempt: recording there would grow the very log the
   command is inspecting, or outlive the directory it removes.

Items 3, 4 and 5 of the issue were already fixed by #40 and #105 and have
existing tests; item 3 gained a static guard against the `elapsed_ms: 0`
regression.

tests/longtail-51.test.ts adds 10 tests. Items 1 and 2 are exercised
through a child process with an isolated HOME, because a real global
config on the developer's machine masks the aliasing. Suite: 866 pass.

No bench case: these are config and telemetry defects, outside the bench
harness's edit-correctness model.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@bigknoxy
bigknoxy merged commit a7b351c into main Aug 19, 2026
4 checks passed
@bigknoxy
bigknoxy deleted the fix/51-longtail-correctness branch August 19, 2026 19:28
bigknoxy pushed a commit that referenced this pull request Aug 19, 2026
## [4.4.15](v4.4.14...v4.4.15) (2026-08-19)

### Bug Fixes

* **#51:** clone config defaults, null-unset route overrides, resettable session, telemetry on every command ([#126](#126)) ([a7b351c](a7b351c)), closes [#51](#51) [#51](#51) [#40](#40) [#105](#105)
@bigknoxy

Copy link
Copy Markdown
Owner Author

🎉 This PR is included in version 4.4.15 🎉

The release is available on GitHub release

Your semantic-release bot 📦🚀

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[P3] Long tail: seven small correctness and hygiene defects

1 participant