Skip to content

feat: telemetry opt-out command; remove hidden records commands - #207

Open
Fermionic-Lyu wants to merge 1 commit into
mainfrom
feat/records-removal-telemetry-opt-out
Open

feat: telemetry opt-out command; remove hidden records commands#207
Fermionic-Lyu wants to merge 1 commit into
mainfrom
feat/records-removal-telemetry-opt-out

Conversation

@Fermionic-Lyu

@Fermionic-Lyu Fermionic-Lyu commented Jul 26, 2026

Copy link
Copy Markdown
Member

Summary

Two changes:

1. insforge telemetry — usage-analytics opt-out

npx @insforge/cli telemetry status    # enabled/disabled + what decides it
npx @insforge/cli telemetry disable   # persists to ~/.insforge/config.json
npx @insforge/cli telemetry enable

Design:

  • One kill switch, every emitter. isTelemetryDisabled() in src/lib/analytics.ts gates both the PostHog client and the legacy reportCliUsage OSS path. DEVELOPMENT.md §2 now requires any new telemetry emitter to check it.
  • Resolution order: DO_NOT_TRACK (the cross-tool convention) → INSFORGE_TELEMETRY_DISABLED (per-run/CI) → telemetry_disabled in the global config (persistent, managed by this command). Explicit falsy values (0, false, empty) don't opt out.
  • Honest status: telemetry enable errors if an env var still forces telemetry off, instead of claiming it's back on; status reports the deciding source.
  • No self-tracking: the telemetry command emits no analytics events — an opt-out flow that phones home undermines the point.
  • Fail-safe: a corrupt config file reads as "enabled"; telemetry handling can never break a command.

reportAgentConnected (dashboard "agent connected" onboarding signal) is deliberately not gated — it drives product behavior, not analytics.

2. Remove the hidden records command group

Never supported for direct use (hidden since introduction); table data goes through db query. Deletes src/commands/records/, the registration in src/index.ts, and updates the README note.

Test plan

  • 12 new tests: env-var precedence (including falsy values), config opt-out, corrupt-config fail-safe, PostHog gating, and the command's status/enable/disable behaviors including the env-override error path.
  • Full suite: 648 passing, lint clean, build clean.
  • Smoke-tested on the built CLI: records errors as an unknown command; telemetry status --json reports default/INSFORGE_TELEMETRY_DISABLED/config sources correctly; disable→enable round-trip verified against a real ~/.insforge/config.json.

🤖 Generated with Claude Code


Summary by cubic

Adds insforge telemetry to manage anonymous usage analytics with a single opt‑out switch. Removes the hidden records commands; use db query for table data.

  • New Features

    • One kill switch for telemetry. Resolution: DO_NOT_TRACKINSFORGE_TELEMETRY_DISABLEDtelemetry_disabled in ~/.insforge/config.json.
    • Gates both PostHog and the legacy reportCliUsage. New emitters must check it (see DEVELOPMENT.md).
    • telemetry status|enable|disable; status explains the deciding source, and enable warns if an env var still keeps it off. The command does not self-track.
    • Corrupt config fails safe (telemetry defaults to enabled so commands never break).
  • Refactors

    • Remove the hidden records group (list/create/update/delete) and its registration. Docs now direct table access through db query.

Written for commit 8b991d6. Summary will update on new commits.

Review in cubic

Note

Add telemetry CLI command with opt-out support and remove hidden records commands

  • Adds a new telemetry command group with status, enable, and disable subcommands that persist opt-out state in the global config via a telemetry_disabled flag in GlobalConfig.
  • Introduces isTelemetryDisabled() in analytics.ts as a centralized kill switch that checks DO_NOT_TRACK and INSFORGE_TELEMETRY_DISABLED env vars and the persisted config; both getClient() and reportCliUsage() now respect it.
  • Removes the hidden records CRUD command group (create, delete, list, update) from the CLI; users are directed to db query instead.
  • Behavioral Change: PostHog events and legacy usage reporting are silently suppressed when telemetry is disabled by env or config.

Macroscope summarized 8b991d6.

Summary by CodeRabbit

  • New Features
    • Added telemetry status, telemetry enable, and telemetry disable CLI commands.
    • Added persistent and per-run controls for anonymous usage analytics, including environment-variable overrides.
  • Changes
    • Removed the records CLI commands for listing, creating, updating, and deleting records. Use db query instead.
  • Documentation
    • Updated command references, environment variable documentation, and telemetry configuration guidance.
  • Tests
    • Added coverage for telemetry status, opt-out behavior, configuration persistence, and environment overrides.

Telemetry opt-out (usage analytics kill switch):
- New `insforge telemetry status|enable|disable` command. `disable`
  persists telemetry_disabled in ~/.insforge/config.json; status reports
  the effective state and what decides it (env var, config, default).
- isTelemetryDisabled() in src/lib/analytics.ts honors, in order:
  DO_NOT_TRACK (consoledonottrack.com convention),
  INSFORGE_TELEMETRY_DISABLED, then the persisted config flag. It gates
  the PostHog client AND the legacy reportCliUsage path, so one switch
  covers every usage-tracking emitter. A corrupt config file reads as
  enabled — telemetry handling must never break the CLI.
- The telemetry command itself deliberately emits no analytics events.
- Documented in README (command + env vars) and DEVELOPMENT.md §2, which
  now requires new telemetry emitters to check the kill switch.

Records removal:
- Delete the hidden `records` command group (list/create/update/delete).
  It was never supported for direct use; table data goes through
  `db query`. README note updated.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Jul 26, 2026

Copy link
Copy Markdown

Review Change Stack

Walkthrough

Changes

Telemetry opt-out

Layer / File(s) Summary
Shared telemetry gating
src/types.ts, src/lib/analytics.ts, src/lib/skills.ts, src/lib/analytics.test.ts
Adds persistent and environment-based opt-out checks and applies them to PostHog and legacy usage reporting, with coverage for enabled, disabled, falsy, and config-error cases.
Telemetry command and registration
src/commands/telemetry.ts, src/commands/telemetry.test.ts, src/index.ts
Adds telemetry status, disable, and enable, persists configuration changes, handles forced environment overrides, and registers the command.
Telemetry documentation
README.md, DEVELOPMENT.md
Documents telemetry commands, environment overrides, persistence, and the shared opt-out requirement for new emitters.

Records command removal

Layer / File(s) Summary
Records command surface removal
src/index.ts, README.md
Removes hidden records command wiring and updates table-query guidance to use db query.

Estimated code review effort: 3 (Moderate) | ~25 minutes

Possibly related PRs

  • InsForge/CLI#131: Adds analytics instrumentation using the shared PostHog client affected by the new opt-out gate.
  • InsForge/CLI#143: Adds setup telemetry that relies on the updated analytics client lifecycle.
  • InsForge/CLI#145: Adds deployment events that are suppressed when telemetry is disabled.

Suggested reviewers: jwfing, carmendou, tonychang04

Poem

A bunny flips the switch tonight,
No stray events take flight.
Three commands bloom, records fade,
Config keeps the choice well made.
Hop, hop—analytics obey!

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 40.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly summarizes the two main changes: telemetry opt-out support and removal of hidden records commands.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/records-removal-telemetry-opt-out

Comment @coderabbitai help to get the list of available commands.

@greptile-apps

greptile-apps Bot commented Jul 26, 2026

Copy link
Copy Markdown

Greptile Summary

Adds a persistent and environment-controlled telemetry opt-out while removing the hidden records command group.

  • Registers telemetry status, enable, and disable commands and extends global configuration with telemetry_disabled.
  • Gates PostHog and legacy CLI-usage emitters through a shared opt-out check.
  • Removes record CRUD command registration and implementation, directing users to db query.
  • Adds telemetry command and analytics opt-out tests and updates user/developer documentation.

Confidence Score: 3/5

The telemetry opt-out needs correction before merging because a corrupt global config prevents users from disabling analytics and environment-overridden disable output reports the wrong source.

The analytics emitters themselves honor the new gate, but the management command does not share its corrupt-config recovery and emits inconsistent machine-readable status under environment overrides.

Files Needing Attention: src/commands/telemetry.ts, src/commands/telemetry.test.ts

Important Files Changed

Filename Overview
src/commands/telemetry.ts Adds telemetry state management, but corrupt config blocks all subcommands and disable can report the wrong deciding source.
src/lib/analytics.ts Adds a shared opt-out resolver and rechecks it before every PostHog capture.
src/lib/skills.ts Applies the shared telemetry gate to legacy OSS CLI-usage reporting.
src/index.ts Registers the telemetry command and removes the hidden records command group.
src/types.ts Extends global configuration with the optional persistent telemetry flag.
src/commands/telemetry.test.ts Covers standard command behavior but omits corrupt-config command handling and environment-overridden disable output.
src/lib/analytics.test.ts Covers environment precedence, persistent opt-out, PostHog gating, and corrupt-config fail-safe behavior.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
  A[Telemetry check] --> B{DO_NOT_TRACK truthy?}
  B -->|Yes| X[Disabled by DO_NOT_TRACK]
  B -->|No| C{INSFORGE_TELEMETRY_DISABLED truthy?}
  C -->|Yes| Y[Disabled by INSFORGE_TELEMETRY_DISABLED]
  C -->|No| D{Global config parses?}
  D -->|No| E[Enabled by fail-safe]
  D -->|Yes| F{telemetry_disabled is true?}
  F -->|Yes| Z[Disabled by config]
  F -->|No| G[Enabled by default]
Loading

Reviews (1): Last reviewed commit: "feat: telemetry opt-out command; remove ..." | Re-trigger Greptile

Comment thread src/commands/telemetry.ts
.action((_opts, cmd) => {
const { json } = getRootOpts(cmd);
try {
const config = getGlobalConfig();

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Corrupt config blocks telemetry control

When ~/.insforge/config.json contains invalid JSON, getGlobalConfig() throws before telemetry disable, enable, or status can complete, causing all three commands to exit with an error and preventing the user from persisting an opt-out until they manually repair the file. This path needs the same corrupt-config fallback used by isTelemetryDisabled().

Knowledge Base Used: CLI Entrypoint and Authentication

Comment thread src/commands/telemetry.ts
config.telemetry_disabled = true;
saveGlobalConfig(config);
if (json) {
outputJson({ enabled: false, source: 'config' });

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Disable reports the wrong source

When telemetry disable --json runs with DO_NOT_TRACK or INSFORGE_TELEMETRY_DISABLED set, this hard-coded response reports source: "config" even though the environment variable has precedence, causing its output to disagree with an immediate telemetry status --json result.

Knowledge Base Used: Account Management

@jwfing jwfing left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review: telemetry opt-out + records removal

Summary: A clean, well-tested telemetry opt-out implemented as a single kill switch that correctly gates every analytics emitter, plus a tidy removal of the dead hidden records group — no blocking issues.

Requirements context

No matching spec/plan found under docs/ — the repo keeps specs in docs/specs/ (only diagnose and db-migrations design docs exist; there is no docs/superpowers/). Assessed against the PR description, DEVELOPMENT.md §2, and the surrounding code.

Findings

Critical

(none)

Suggestion

  • Software engineering — duplicated falsy-env parsing (src/commands/telemetry.ts:9-15 vs src/lib/analytics.ts:8-31). telemetry.ts reimplements the "set to anything except an explicit falsy value" rule (envOverride()/flag()) that already lives in analytics.ts (envFlag()/isTelemetryDisabled()). The command needs the source name (DO_NOT_TRACK vs INSFORGE_TELEMETRY_DISABLED), which isTelemetryDisabled() doesn't expose, so the duplication is understandable — but two independent copies of the same precedence + falsy rule can drift, and if they do, telemetry status would report a source that disagrees with what actually gates emission. Consider exporting a single resolver from analytics.ts (e.g. one that returns {disabled, source}) and having both isTelemetryDisabled() and the command consume it.

  • Functionality — corrupt config isn't fail-safe in the command path (src/commands/telemetry.ts:33-38, 38-50, 52-73). isTelemetryDisabled() deliberately treats a corrupt ~/.insforge/config.json as "enabled" (try/catch), so telemetry keeps flowing. But status/disable/enable call getGlobalConfig() unguarded, and config.ts:29-30 JSON.parses with no try/catch — so with a corrupt config, telemetry disable throws and exits instead of opting the user out. Net effect: the one state where telemetry is silently on (corrupt config → fail-safe "enabled") is also the state where the persistent opt-out command fails, leaving only the env var as an escape. Low blast radius, but mirroring the PR's own fail-safe stance (e.g. disable starting from a default config when the file is unreadable) would be more robust.

Information

  • Performance — isTelemetryDisabled() re-reads config per emission (src/lib/analytics.ts:23-31, 36). getClient() now calls getGlobalConfig() → synchronous readFileSync + JSON.parse on every telemetry event, and the result isn't memoized even though the PostHog client is cached. Negligible for a one-shot CLI (typically one event per invocation), noting only in case an event ever fires in a loop.

  • Security — no concerns. No new user input reaches SQL/shell/HTTP; the command only writes a boolean to config. No secrets/PII newly logged. This PR is net-positive for privacy (adds opt-out) and the records removal shrinks the OSS-fetch surface. No new dependencies.

  • Software engineering — coverage & conventions are solid. 12 new tests exercise env precedence (including explicit-falsy 0/false), config opt-out, corrupt-config fail-safe, PostHog gating, and the enable env-override error path. Import style (.js suffixes, node: prefixes), error handling (handleError/CLIError), and the "no self-tracking" note are consistent with the codebase. The kill switch is genuinely centralized — verified command-telemetry.ts (trackCommandUsage/trackTopLevelUsage) routes through captureEvent → getClient(), so it's gated too, and no orphaned records references remain after the deletion. DEVELOPMENT.md now documents the opt-out contract for future emitters.

Verdict

approved (no Critical findings). Suggestions above are non-blocking. Note: this is the bot's assessment for reporting — the GitHub green-check approval remains a separate human action.

@jwfing jwfing left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM - approved.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/lib/analytics.ts`:
- Around line 14-31: Centralize telemetry-state resolution in
src/lib/analytics.ts#L14-L31 by exporting envFlag and adding a shared resolver
that applies the environment and config rules with consistent corrupt-config
handling; preserve the intended fail-safe behavior for unreadable configuration.
In src/commands/telemetry.ts#L9-L29, remove the duplicated envOverride and
direct config lookup from resolveStatus and reuse the shared analytics resolver
so telemetry status and emitters always report the same state.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 788c8adb-dc1f-4812-ba01-bcf30768fc2f

📥 Commits

Reviewing files that changed from the base of the PR and between 0a085f2 and 8b991d6.

📒 Files selected for processing (13)
  • DEVELOPMENT.md
  • README.md
  • src/commands/records/create.ts
  • src/commands/records/delete.ts
  • src/commands/records/list.ts
  • src/commands/records/update.ts
  • src/commands/telemetry.test.ts
  • src/commands/telemetry.ts
  • src/index.ts
  • src/lib/analytics.test.ts
  • src/lib/analytics.ts
  • src/lib/skills.ts
  • src/types.ts
💤 Files with no reviewable changes (4)
  • src/commands/records/update.ts
  • src/commands/records/delete.ts
  • src/commands/records/create.ts
  • src/commands/records/list.ts

Comment thread src/lib/analytics.ts
Comment on lines +14 to +31
/**
* Usage-tracking kill switch, honored by every telemetry emitter (PostHog
* here, `reportCliUsage` in skills.ts). Resolution order:
* 1. `DO_NOT_TRACK` — the cross-tool convention (consoledonottrack.com)
* 2. `INSFORGE_TELEMETRY_DISABLED` — per-run / CI override
* 3. `telemetry_disabled` in ~/.insforge/config.json — persistent opt-out
* managed by `insforge telemetry enable|disable|status`
* A corrupt config file must never break the CLI, so it reads as "enabled".
*/
export function isTelemetryDisabled(): boolean {
if (envFlag(process.env.DO_NOT_TRACK)) return true;
if (envFlag(process.env.INSFORGE_TELEMETRY_DISABLED)) return true;
try {
return getGlobalConfig().telemetry_disabled === true;
} catch {
return false;
}
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔒 Security & Privacy | 🟠 Major | ⚡ Quick win

Telemetry-state resolution is duplicated between analytics.ts and telemetry.ts, with diverging corrupt-config behavior. analytics.ts owns the real kill switch (isTelemetryDisabled/envFlag) but doesn't export it for reuse; telemetry.ts re-implements the same env checks (envOverride) and its own config lookup (resolveStatus) without the same fail-safe catch, so a corrupt config.json produces an inconsistent outcome: analytics silently stays enabled, while telemetry status throws a hard error. This also means the two implementations can drift out of sync if the flag rules ever change in only one place.

  • src/lib/analytics.ts#L14-L31: export envFlag (and ideally a resolveTelemetryState() helper that also returns the deciding source) so telemetry.ts can reuse it instead of re-implementing it; also reconsider whether the catch should fail closed (treat unreadable config as still-disabled) rather than silently re-enabling a previously persisted opt-out.
  • src/commands/telemetry.ts#L9-L29: replace envOverride()/the config lookup in resolveStatus() with the shared helper from analytics.ts, and wrap the config read in the same fail-safe catch so telemetry status can't diverge from the actual kill switch during a corrupt config.
📍 Affects 2 files
  • src/lib/analytics.ts#L14-L31 (this comment)
  • src/commands/telemetry.ts#L9-L29
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/lib/analytics.ts` around lines 14 - 31, Centralize telemetry-state
resolution in src/lib/analytics.ts#L14-L31 by exporting envFlag and adding a
shared resolver that applies the environment and config rules with consistent
corrupt-config handling; preserve the intended fail-safe behavior for unreadable
configuration. In src/commands/telemetry.ts#L9-L29, remove the duplicated
envOverride and direct config lookup from resolveStatus and reuse the shared
analytics resolver so telemetry status and emitters always report the same
state.

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

3 issues found across 13 files

Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name="src/commands/telemetry.ts">

<violation number="1" location="src/commands/telemetry.ts:27">
P2: `telemetry status` fails when the global config is malformed, despite the fail-safe policy that corrupt config reads as enabled. Catch the config read here too so status remains usable for users trying to diagnose or recover telemetry settings.</violation>

<violation number="2" location="src/commands/telemetry.ts:70">
P2: The JSON output here hard-codes `source: 'config'` but this disagrees with `telemetry status --json` when an env var like `DO_NOT_TRACK` or `INSFORGE_TELEMETRY_DISABLED` is set. Since env vars take precedence over config in `resolveStatus()`, the disable output should reflect the actual deciding source — consider calling `resolveStatus()` after the save and returning its result, so both commands report a consistent view.</violation>
</file>

<file name="src/lib/analytics.test.ts">

<violation number="1" location="src/lib/analytics.test.ts:60">
P3: Missing precedence test: env vars should win over the persistent config, but no test asserts this. Consider adding a test that sets DO_NOT_TRACK=1 (or INSFORGE_TELEMETRY_DISABLED=true) while getGlobalConfig returns telemetry_disabled: false and verifies isTelemetryDisabled() is still true. This would lock in the resolution order documented in the PR description.</violation>
</file>

Reply with feedback, questions, or to request a fix.

Re-trigger cubic

Comment thread src/commands/telemetry.ts
function resolveStatus(): TelemetryStatus {
const env = envOverride();
if (env) return { enabled: false, source: env };
const disabled = getGlobalConfig().telemetry_disabled === true;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2: telemetry status fails when the global config is malformed, despite the fail-safe policy that corrupt config reads as enabled. Catch the config read here too so status remains usable for users trying to diagnose or recover telemetry settings.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At src/commands/telemetry.ts, line 27:

<comment>`telemetry status` fails when the global config is malformed, despite the fail-safe policy that corrupt config reads as enabled. Catch the config read here too so status remains usable for users trying to diagnose or recover telemetry settings.</comment>

<file context>
@@ -0,0 +1,106 @@
+function resolveStatus(): TelemetryStatus {
+  const env = envOverride();
+  if (env) return { enabled: false, source: env };
+  const disabled = getGlobalConfig().telemetry_disabled === true;
+  return { enabled: !disabled, source: disabled ? 'config' : 'default' };
+}
</file context>

Comment thread src/commands/telemetry.ts
config.telemetry_disabled = true;
saveGlobalConfig(config);
if (json) {
outputJson({ enabled: false, source: 'config' });

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2: The JSON output here hard-codes source: 'config' but this disagrees with telemetry status --json when an env var like DO_NOT_TRACK or INSFORGE_TELEMETRY_DISABLED is set. Since env vars take precedence over config in resolveStatus(), the disable output should reflect the actual deciding source — consider calling resolveStatus() after the save and returning its result, so both commands report a consistent view.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At src/commands/telemetry.ts, line 70:

<comment>The JSON output here hard-codes `source: 'config'` but this disagrees with `telemetry status --json` when an env var like `DO_NOT_TRACK` or `INSFORGE_TELEMETRY_DISABLED` is set. Since env vars take precedence over config in `resolveStatus()`, the disable output should reflect the actual deciding source — consider calling `resolveStatus()` after the save and returning its result, so both commands report a consistent view.</comment>

<file context>
@@ -0,0 +1,106 @@
+        config.telemetry_disabled = true;
+        saveGlobalConfig(config);
+        if (json) {
+          outputJson({ enabled: false, source: 'config' });
+        } else {
+          outputSuccess('Telemetry disabled. No usage analytics will be sent.');
</file context>

Comment thread src/lib/analytics.test.ts
@@ -0,0 +1,84 @@
import { describe, it, expect, vi, beforeEach, afterEach, type Mock } from 'vitest';

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P3: Missing precedence test: env vars should win over the persistent config, but no test asserts this. Consider adding a test that sets DO_NOT_TRACK=1 (or INSFORGE_TELEMETRY_DISABLED=true) while getGlobalConfig returns telemetry_disabled: false and verifies isTelemetryDisabled() is still true. This would lock in the resolution order documented in the PR description.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At src/lib/analytics.test.ts, line 60:

<comment>Missing precedence test: env vars should win over the persistent config, but no test asserts this. Consider adding a test that sets DO_NOT_TRACK=1 (or INSFORGE_TELEMETRY_DISABLED=true) while getGlobalConfig returns telemetry_disabled: false and verifies isTelemetryDisabled() is still true. This would lock in the resolution order documented in the PR description.</comment>

<file context>
@@ -0,0 +1,84 @@
+  it('treats explicit falsy env values as not opting out', async () => {
+    vi.stubEnv('DO_NOT_TRACK', '0');
+    vi.stubEnv('INSFORGE_TELEMETRY_DISABLED', 'false');
+    const { isTelemetryDisabled } = await loadAnalytics();
+    expect(isTelemetryDisabled()).toBe(false);
+  });
</file context>

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants