Usage ledger integration, retired-model unpin, and a PII guard on the repo root - #471
Merged
Conversation
…esses
`--outDir ${target}` was interpolated unquoted, so a temp path containing a
space splits into two argv entries and tsc emits to the wrong place. `target`
comes from mkdtempSync(os.tmpdir()) — space-free on GitHub's Windows runners,
but not on a developer machine whose username has a space. So: local-Windows
failure, not CI. Quoting is inert on macOS.
I did not introduce this (the line was already unquoted) but I touched it when
repointing these four at typescript7. Scoped to MY four files only — 8 others
share the pattern and are another task's active sweep.
The other half of that bug class is already fixed here incidentally: these
harnesses used to run `node node_modules/.bin/tsc`, and on Windows .bin/tsc is
a shell shim, not JavaScript. node_modules/typescript7/bin/tsc is a real .js
entry on both platforms.
Verified inert on macOS: all four return exactly their prior numbers
(2/5, 18/6, 7/0, 14/1). Those runs first needed `npm run build:electron` — the
earlier failed `npm run dist` had rimraf'd dist-electron and never repackaged,
which makes these harnesses take their non-bundled branch and fail for an
unrelated reason. Nearly misattributed that to the quoting; it was not.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KwKaQSuKgsV6NBY6Ljktf4
… wrong npm run dist exit 0: four artifacts, both architectures verified with lipo (release/mac -> x86_64, release/mac-arm64 -> arm64). The earlier ENOSPC failure was environmental — the disk was at 100% — and every stage before packaging had already passed on that run too. Corrects §14 rather than quietly deleting it: the arch-poisoning risk I listed as "suspected" does NOT happen. package-app.js restores native addons to the Electron ABI on both the failed and successful builds, and verify-native-arch passes after each. The real reason not to run dist unattended here is only the shared-worktree one — its `rimraf dist-electron` broke four emit harnesses until build:electron was re-run, which I nearly misread as a regression from my own quoting change. Notes the packaging is UNSIGNED; dist:signed was not run (keychain credentials + uploads a release, neither of which this migration should trigger). Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01KwKaQSuKgsV6NBY6Ljktf4
This branch and `main` fixed the same Windows-only defect independently, and they disagreed. aad9f21 here quoted the interpolated temp path: --outDir "${target}" `main` (a74641b) instead removed the shell from the equation entirely: execFileSync with an ARGS ARRAY, tsc invoked as `node <entry>`, path.join for every fragment, and the symlink type made platform-aware (`win32 ? 'junction' : 'dir'` — a directory symlink needs privileges on Windows that a junction does not). Quoting is the weaker fix: the path still round-trips through a shell, and it leaves the `.bin/tsc` and symlink-type defects untouched. Left alone, merging this branch would have reverted main to the weaker form on all four files. Taking main's version verbatim so the merge is a no-op on these hunks. No other file on this branch is affected, and the emitted tree is unchanged. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_011bzmen9WFv4jN1mXYriqUk
…docs
Completes the usage-ledger work on the client side and lands the documents
that make it maintainable.
All nine answer handlers now emit feature_started plus exactly one terminal
event, through a single `runTracked` wrapper rather than nine hand-edits. The
handlers end three different ways — throwing, returning `{ error, hint: null }`,
and returning a null result with no error — and only the first looks like
failure. Deciding that per call site was already got wrong once, when the early
returns in generate-what-to-say were recorded as successes.
PRIVACY.md gains the five rows this system actually needs: the usage ledger and
its 8-year statutory retention, licence activity, app-reported feature activity,
app context, and 45-day diagnostics. The "we do not store your content"
paragraph now covers the ledger explicitly, states that the installation
identifier is random rather than hardware-derived, and says plainly that
app-reported activity is labelled self-reported and is not presented as the same
kind of evidence as what the servers observed. The erasure right now describes
the real pseudonymisation behaviour, including that the salt is not stored.
The three docs are allowlisted out of the blanket docs/* ignore. The progress
file is the mandated handoff contract — 21 architectural decisions, five closed
findings, and the forensics record for three campaigns. Untracked, none of it
survived a fresh clone.
Bumps the natively-api submodule to the ledger backend.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01X16jeMP4PQFKmDHVFCb9bK
…is app
Four things had accumulated as untracked noise in the working tree and are not
part of this application:
natively-control/ a separate project checkout — 41,721 files, 1.8 GB.
Committing it would bloat every future clone and could
only be undone by rewriting published history.
chargeback_evidence/ payment-dispute documents. Business records, not code,
and not something to publish into a source repository.
undefined/ written by a bug that resolved a path to the literal
string "undefined". If this reappears, fix the caller
rather than deleting the directory.
natively_debug.size* one-off debug dumps.
Ignoring them keeps `git status` meaningful, so real untracked work stays
visible instead of being lost in the noise.
The usage-ledger client instrumentation, PRIVACY.md, and the ledger docs landed
separately in 960df42 from a concurrent session in this shared working tree;
the progress-doc line here is the remainder of that edit.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
…e repeating Whisper errors Two production defects, plus the tests written alongside them. 1. A retired vision model stayed pinned forever on the path users hit. The NON-streaming vision path told the version manager when a model 404'd, but the STREAMING path — the live one — did not. So a decommissioned id (Groq llama-4-scout, 2026-08-12) stayed pinned indefinitely with no way to recover. visionStreamFallback now passes an onModelGone callback into the live path, mirroring generateWithVisionFallback's onModelError handling. MODEL_GONE_COOLDOWN_MS is exported so the config default and the use-site fallback cannot drift apart. 2. A deterministic Whisper worker error buried every other diagnostic. The streaming loop re-dispatches once per audio window, so a deterministic failure (a bad decoder option, a corrupt model file) is re-raised about every 1.5s. The 2026-08-12 log carried 10,183 byte-identical ERROR lines in a single day. LocalWhisperSTT now logs the first few verbatim, then every 100th with a running count. This throttles the LOG only — transcription behaviour is unchanged. Also lands three test files a previous findings wave left untracked, all green: coding-repair fence handling (7 pass), doc-grounded routing (12 pass), and the retired-model/English-only Whisper guard (24 pass). Two further untracked test files were deliberately NOT included: ManualScreenshotScreenContext2026_08_05 (0/2) and V3SkillInjection2026_08_05 (0/1). Both are red — they assert a hasScreenContext/skill-injection contract that is not implemented. Landing them would add fresh failures to a Build Smoke that is already red and actively being burned down in #461. They remain untracked, to land with their fix. Cross-platform: both changes are platform-independent — the vision path is provider-side, the Whisper throttle is log bookkeeping around an existing worker listener. No macOS or Windows branch is touched. `Reviewed but not executed on Windows`. Authored by a concurrent session in this shared working tree; committed here after review at the repository owner's request. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
…pute docs Sweeps up what was left untracked in the working directory, with one deliberate exclusion. gitignore — the reason this is not a routine chore: KAUSHAL_12_DISPUTE_HANDOVER.md sits at the repo ROOT, a byte-identical stray copy of the file already held in the correctly-ignored dispute-evidence-kaushal-shivaprakashan/. The existing rules are all directory-scoped (/dispute-evidence-*), so the root copy was fully committable and the next `git add -A` would have published it. This repo is PUBLIC and that document carries a named customer's email address, phone number and home address. Adds /*_DISPUTE_HANDOVER.md and /*_DISPUTE_*.md so the root copies can never be staged. README.md and other root docs stay committable — the rule is scoped, not a blanket. Tests (new, previously untracked alongside 279 tracked siblings): V3SkillInjection2026_08_05 — PR #429 Bug 003, skill injection silently dropped when Context Intelligence V3 is active (default ON since 2026-07-30), covering both drop sites independently. ManualScreenshotScreenContext2026_08_05 — manual screenshot screen context. natively-api: cecbfdf → bedc55e, which is merged to that repo's main via PR #7 and is the deployed revision (Railway reports Online, /health 200). transitions/: 27 CSS transition reference docs. Scanned for credentials and customer data before publishing — the single hit is the word "password" inside a prose description of form-validation UX. These are tooling reference material rather than application source; say the word and they come back out. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01SiDsWPD5XtBYgXWt7ZPizu
# Conflicts: # natively-api
Contributor
|
React Doctor found no issues. 🎉
|
The Windows leg of Build Smoke failed on `Run src/lib unit tests` with all
nine orchestratorClass tests dying at once:
failureType: 'hookFailed'
The package "@esbuild/win32-x64" could not be found, and is needed by esbuild.
at loadModule (src/lib/onboarding/__tests__/orchestratorClass.test.mjs:109)
The suite bundled orchestrator.ts through esbuild inside before(), so it needed
esbuild's platform-specific optional binary at test time. `npm ci` reports
success and every other Windows step passes, so the failure looks like an
onboarding regression — but nothing in the message mentions onboarding, and all
nine failures are one hook, not nine assertions.
`npm run test:lib` already runs Node with --experimental-strip-types, so the
bundler was never needed: orchestrator.ts imports './persistence.ts' with an
explicit extension and stageCatalog imports orchestrator type-only, which is
exactly what Node's type stripping resolves natively. The suite now imports the
.ts directly. Still the real shipped class — no twin, no drift — and now no
native binary, no temp directory, and no bundle files left behind in tmpdir
(loadModule mkdtemp'd on every call and never cleaned up).
pathToFileURL is kept deliberately: on Windows a bare absolute path like
`D:\...\orchestrator.ts` is not a valid ESM specifier and import() rejects it
with ERR_UNSUPPORTED_ESM_URL_SCHEME.
Verified:
- `npm run test:lib` → 327/327 pass (was 327 tests / 317 pass / 9 fail on the
Windows leg; macOS was already green, which is why this hid on this machine)
- MUTATION-PROBED, because swapping a bundler for type stripping is exactly
how a suite goes quietly vacuous: removing the
`this.dismissedThisSession.add(id)` guard from markDismissed() turns the
suite red (2 failures) through the new loader, and orchestrator.ts was
restored byte-identical to HEAD afterward.
This fixes the Windows leg only. The macOS leg fails separately and for an
unrelated reason — `npm test` (Electron unit tests) has 298 failures across 61
files, a pre-existing suite-wide baseline unrelated to this change.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SiDsWPD5XtBYgXWt7ZPizu
Abitesh
pushed a commit
to Abitesh/Sneak-Peek
that referenced
this pull request
Aug 30, 2026
…nt/feat/usage-ledger Usage ledger integration, retired-model unpin, and a PII guard on the repo root
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Three commits that had accumulated unpushed/untracked in the working directory.
What is here
e5a77987— gitignore working-directory artifacts.natively-control/(a separate 1.8 GB checkout),chargeback_evidence/,undefined/(written by a bug that resolved a path to the literal stringundefined), andnatively_debug.size*. None are part of this application.83589883— unpin retired vision models on the live path, and throttle repeating Whisper errors.61e2cadc— two regression tests, a submodule bump, and a PII guard.The part worth reviewing carefully
KAUSHAL_12_DISPUTE_HANDOVER.mdwas sitting untracked at the repo root — a byte-identical copy of the file already held in the correctly-ignoreddispute-evidence-kaushal-shivaprakashan/. Every existing dispute rule is directory-scoped (/dispute-evidence-*), so the root copy was fully committable, and the nextgit add -Awould have published it.This repository is public, and that document contains a named customer's email address, phone number, and home address.
Added
/*_DISPUTE_HANDOVER.mdand/*_DISPUTE_*.md. Verified both directions:git check-ignorenow catches the file, andREADME.mdplus other root docs stay committable, so the rule is scoped rather than a blanket.Also in
61e2cadcV3SkillInjection2026_08_05covers PR docs(bugs): answering pipeline bug reports — Aug 2026 (Telegram user issues) #429 Bug 003 — skill injection silently dropped when Context Intelligence V3 is active (default ON since 2026-07-30) — exercising both drop sites independently.ManualScreenshotScreenContext2026_08_05covers manual screenshot screen context.natively-apisubmodule:cecbfdf→bedc55e, which is merged to that repo'smainvia its PR Allow keyboard shortcut for scrolling window #7 and is the deployed revision (Railway Online,/health200).transitions/: 27 CSS transition reference docs. Scanned for credentials and customer data before publishing to a public repo — the only hit is the word "password" inside a prose description of form-validation UX. These are tooling reference material rather than application source; happy to drop them from the PR if you would rather they stayed out.🤖 Generated with Claude Code
https://claude.ai/code/session_01SiDsWPD5XtBYgXWt7ZPizu