Skip to content

Say it once when the trial ends and the diagram freezes (0.18.0) - #150

Merged
bogatyrjov1 merged 1 commit into
mainfrom
disclose-frozen-map
Aug 4, 2026
Merged

Say it once when the trial ends and the diagram freezes (0.18.0)#150
bogatyrjov1 merged 1 commit into
mainfrom
disclose-frozen-map

Conversation

@bogatyrjov1

Copy link
Copy Markdown
Contributor

The silence this closes

An elapsed trial stops two things: new decisions are no longer stored, and the "How it works" diagram stops updating. The capture endpoint reports it as a 200 skip (captureSkipped: 'trial_expired', count 0) — deliberately never an error, because a capture hook that starts failing is a capture hook that gets uninstalled, and nothing already captured is lost.

The cost of that design is that from inside the agent it looked like everything still worked. This closes it with one line, once per session.

What it says, and why it is worded that way

backthread: your trial has ended — your "How it works" diagram has stopped updating and new decisions aren't being captured. Everything captured so far stays readable: <billing url>

A correctness notice, not a pitch. That a map you rely on has stopped being true is worth saying on its own merits; the link is there because it is the fix, not because it is the point. A nag inside someone's coding agent is the fastest way to get uninstalled — so: one line, on stderr, never mid-flow.

How it is throttled

It reuses the existing once-per-session ring that the free-plan limit line already uses (claimSessionOnce, same file, same 0600 state file). Consequences inherited for free:

  • Manual and MCP captures can fire many times in one session; only the first prints.
  • A new session prints again — once per session, not once per machine.
  • No identifiable session id → silence, rather than risk printing on every capture.
  • Best-effort and non-throwing throughout, so it cannot break the always-exit-0 capture contract.

It takes priority over the connect / next-step nudges, exactly as the free-plan line does: a frozen repo is connected and healthy, so nothing else would say it.

Validators

Four cases in cli/src/connectNudge.test.ts:

  • the first skip in a session prints and names the diagram; two further skips in the same session print nothing; a new session prints again;
  • it wins over a connect nudge;
  • it is a distinct message from the free-plan limit line, is one line, and points at billing;
  • an unrecognised skip reason prints nothing — a wrong line about someone's own account is worse than no line.

CLI suite 647 → 651, all passing. Repo typecheck clean.

Not in this release

The matching staleness note on query / /backthread:how answers — "answering from your diagram as of <date>, N commits since aren't included" — is composed and served by the server, so its wording and its numbers stay tunable without a publish. It needs no client change and will appear on already-installed versions.

Version bumped to 0.18.0 across the four lockstep files with the committed bundle rebuilt, per RELEASING.md.

….18.0)

An elapsed trial stops two things: new decisions are no longer stored, and
the "How it works" diagram stops updating. Both were entirely silent. The
capture keeps succeeding (a 200 skip with count 0, never an error, nothing
already captured lost), so from inside the agent it simply looked like it
was still working.

The CLI now prints one line the first time a session hits that skip: the
diagram has stopped updating, and where to keep it live. It rides the
existing once-per-session throttle used by the free-plan limit line -
same file, same ring, same best-effort posture - so it can never
interrupt or fail a capture, and a session with no identifiable id stays
silent rather than risk repeating itself on every capture.

It is written as a correctness notice rather than a pitch. That a map you
rely on has stopped being true is worth saying on its own; the link is
there because it is the fix, not because it is the point. A nag inside
someone's coding agent is the fastest way to get uninstalled.

A captureSkipped reason this version does not recognise prints nothing. A
wrong line about someone's own account is worse than no line.

The matching staleness note on query / how answers is composed and served
by the worker, so the wording and the numbers stay tunable without a
publish - no client change here for it.
@bogatyrjov1

Copy link
Copy Markdown
Contributor Author

Self-review of this diff.

REVIEWER: [MEDIUM — checked, correct as written] The throttle ring is SHARED with the connect nudge.
nudgeOncePerSession claims the same per-session ring for the connect nudge, the pre-send "not connected" nudge, the free-plan line and now this one — so a session that already burned the claim would swallow this line. Traced it: a trial_expired skip only ever comes back for a repo that is connected and healthy, so no connect nudge can have fired in that session, and the pre-send scope check would have skipped the send entirely (never reaching this code) if it weren't. The shared ring is also the property that guarantees a session gets at most one of these lines total, which is the behaviour we want. No change.

REVIEWER: [MEDIUM — deliberate] The unrecognised-reason branch is a validator, not an oversight.
captureSkipped is a server-owned open string, and a client that guesses at an unfamiliar value would print a confident, wrong statement about someone's own account. The chain matches two known reasons and falls through to the existing logic for everything else, with a test pinning it. This is the branch most likely to be "helpfully" widened later; it should not be.

REVIEWER: [NIT — accepted] The line carries a billing URL.
Arguably a correctness notice should carry no CTA at all. Kept, because the link is the fix and omitting it would just make the user search for it — but the sentence is ordered so the fact leads and the link trails, and the copy never says "upgrade".

Checked and found correct, for the record:

  • "Everything captured so far stays readable" is literally true — the freeze stops new capture and new snapshots; existing decisions and the last diagram keep serving.
  • Customer vocabulary: the line says "How it works", never the internal noun (asserted in the test).
  • Not phrased as a failure (asserted): the capture genuinely succeeded, and a hook that starts reporting errors is a hook that gets uninstalled.
  • Version lockstep across the four files + the committed bundle rebuilt; git diff --exit-code cli/dist-bundle/backthread.js is clean against a fresh npm run bundle.

CLI suite 647 → 651, all passing; root npm test (the release gate) green; repo typecheck clean.

CI note: the red check is the npm audit high+ vulnerability gate, which fails on transitive dev dependencies and has failed on every push to main for weeks — it aborts before typecheck / test / bundle-sync ever run, so those were verified locally instead (results above). It is unrelated to this diff and pre-dates it.

@bogatyrjov1
bogatyrjov1 merged commit 9a342f7 into main Aug 4, 2026
1 check failed
@bogatyrjov1
bogatyrjov1 deleted the disclose-frozen-map branch August 4, 2026 20:03
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