This release includes breaking changes for platform teams planning a safe upgrade.
✓ No known CVEs patched in this version
Topics
+14 more
Affected surfaces
Summary
AI summaryFeedback stats now emit structured actionable remediation objects alongside prose recommendations.
Full changelog
[email protected]
Release Links
- npm: https://www.npmjs.com/package/thumbgate/v/1.16.0
- GitHub Release: https://github.com/IgorGanapolsky/ThumbGate/releases/tag/v1.16.0
- Compare: https://github.com/IgorGanapolsky/ThumbGate/compare/v1.15.0...v1.16.0
- Publish workflow: https://github.com/IgorGanapolsky/ThumbGate/actions/runs/24918825019
- npm published at: 2026-04-25T01:06:25.567Z
- npm shasum:
e1370dff819073a4ed4e98038c50afc1833b3707 - npm tarball: https://registry.npmjs.org/thumbgate/-/thumbgate-1.16.0.tgz
- Release ref: 679d20e359a16c2254250a1cf3db5cc70128556b
npm Email Companion
npm controls the native "Successfully published" email template, so the email itself stays short. Treat this generated artifact as the full release-note companion for that email: it carries the Changeset summaries, CHANGELOG entry, publish workflow, npm tarball, and shasum when available.
Full Changeset Release Notes
Patch Changes
.changeset/anthropic-api-control-plane.md
Add provider-native action normalization for Anthropic tool use, OpenAI tool calls, and MCP tools/resources/prompts payloads, including token/cost budget enforcement before workflow execution.
CHANGELOG.md Entry
1.16.0
Minor Changes
-
#1122
de61abeThanks @IgorGanapolsky! - feat(feedback-stats): emit structuredactionableRemediationsalongside proserecommendationsanalyzeFeedback()/feedback_statsnow returns a machine-actionableactionableRemediationsarray parallel to the existing proserecommendationslist. Each entry has:{ type: 'skill-improve' | 'pattern-reuse' | 'trend-declining' | 'trend-degrading' | 'high-risk-domain' | 'high-risk-tag' | 'delegation-reduce' | 'delegation-policy-review' | 'diagnose-failure-category', target: string, // skill name, tag, domain, or failure category evidence: { ... }, // numeric signal (counts, rates) that triggered the rule action: string, // canonical action verb consumers can switch on rationale: string, // human-readable explanation of why this fired }This lets hooks and agents act on recommendations programmatically without regex-parsing prose strings. Prose output is unchanged and fully backwards-compatible; the new field is always present (empty array when no recommendations fire).
-
#1198
17ec44bThanks @IgorGanapolsky! - feat(adapters): Cline adapter for Roo Code sunset captureAdds a first-class Cline adapter (
adapters/cline/.mcp.json,.clinerules,INSTALL.md) and wiresnpx thumbgate init --agent clineto auto-register the ThumbGate MCP server in Cline's VS Code globalStorage settings and drop.clinerulesinto the project root. Updates README, landing page, and compare page to list Cline alongside Claude Code, Cursor, Codex, Gemini CLI, Amp, and OpenCode. Captures migration audience from Roo Code's announced 2026-05-15 shutdown. -
#1161
a46785cThanks @IgorGanapolsky! - Surface per-slug/go/:slughits, checkout starts, and conversion rate on the
dashboard telemetry feed.getTelemetryAnalyticsnow exposes atrackedLinks
panel (totalHits,totalCheckoutStarts,overallConversionRate,
bySlug.<slug>.{hits,checkoutStarts,conversionRate},topSlug) so the
/v1/dashboardAPI and/dashboardUI can show which tracked links actually
drive checkouts. CLI telemetry is excluded from the rollup (web-only). -
#1264
d631dddThanks @IgorGanapolsky! - feat(api): push dashboard updates over Server-Sent Events on/v1/eventsApplies the "persistent channel beats per-turn HTTP round trip" pattern (the thesis of OpenAI's 2026-04 Responses-API WebSocket post) to the ThumbGate dashboard. Instead of re-fetching
/v1/feedback/statson a manual refresh, clients now subscribe once to/v1/eventsand receive pushed frames as feedback/rule-regen events happen.Surface:
GET /v1/events— Bearer-authed SSE stream. On connect the server emits anevent: connectedframe with the current server version; thereafter everyPOST /v1/feedback/captureemits anevent: feedbackframe (signal + tags + feedbackId + promoted) and everyPOST /v1/feedback/rulesemits anevent: rules-updatedframe (path). Heartbeat comment frames every 25s keep Railway / proxy idle timers from closing the connection.- Dashboard client (
public/dashboard.html) — subscribes immediately afterconnect()usingfetch()+ReadableStream(needed instead of nativeEventSourceso we can sendAuthorization: Bearer …). On any event the client re-pulls/v1/feedback/statsand re-renders the summary cards.
Non-breaking: existing polled
/v1/feedback/stats,/v1/dashboard, and/v1/feedback/rulesendpoints are unchanged. Clients that don't open/v1/eventsbehave exactly as before.Why: manual refresh was the only way to see new feedback land in the dashboard, which made live demo sessions awkward and hid the real-time nature of the feedback loop. SSE is the right tool for server→client pushes here — no WebSocket upgrade dance, no extra deps, survives Railway's proxy with
X-Accel-Buffering: no. -
#1269
5ce97bfThanks @IgorGanapolsky! - feat(newsletter): send welcome email via Resend on subscriptionNew subscribers to the ThumbGate newsletter now receive an immediate welcome email with the "one AI mistake prevented per email" framing and a CTA to thumbgate.ai/pro.
The
/api/newsletterendpoint fires the send in the background (Promise-then pattern) so the HTTP response stays fast and never fails on mailer errors. Missing RESEND_API_KEY degrades gracefully to a logged warning; the subscriber is still recorded.
Patch Changes
-
#1140
d675466Thanks @IgorGanapolsky! - Add Anthropic-aligned prompt caching and JSON response handling to the
public ThumbGate shell, and persist prompt evaluation evidence in CI so
regressions are easier to catch before release. -
#1153
b9d7f2cThanks @IgorGanapolsky! - fix(api): lazy-load commercial offer private boundaryMove the commercial-offer helpers used by the hosted billing checkout
path behind the private API module loader. The hosted runtime keeps the
same behavior when the module exists, while partially extracted or
public-shell deployments now fail with the standard
PRIVATE_CORE_REQUIREDcontract instead of assuming commercial offer
logic is always bundled.This pins the current split at the checkout boundary:
- checkout attribution parsing now resolves plan/cycle/seat helpers
through the private API module loader. - checkout offer summaries now resolve pricing constants through the
private API module loader. - API regression coverage asserts that
/v1/billing/checkoutreturns
503 when the commercial-offer module is absent.
- checkout attribution parsing now resolves plan/cycle/seat helpers
-
#1153
b9d7f2cThanks @IgorGanapolsky! - fix(api): lazy-load lesson search and semantic private boundariesMove the remaining lesson-search and semantic-schema routes in the HTTP
API server behind the private API module loader. The hosted runtime keeps
the current behavior when those modules are present, while public-shell
or partially extracted runtimes now fail with the standard
PRIVATE_CORE_REQUIRED503 instead of assuming the modules are always
bundled.This pins two more hosted-only edges:
/v1/lessons/searchnow resolves through the lesson-search private
boundary./v1/semantic/describenow resolves through the semantic-layer
private boundary.- API regression tests cover both the normal route behavior and the
unavailable-module fallback contract.
-
#1153
b9d7f2cThanks @IgorGanapolsky! - fix(api): lazy-load lesson synthesis private boundaryMove lesson record read/write flows behind the private API loader so export, import, and lesson detail mutations fail with the standard private-core contract when the hosted lesson synthesis module is unavailable.
-
#1130
5dcc446Thanks @IgorGanapolsky! - chore(brand): canonical TG monogram on README + Stripe coherenceThe canonical ThumbGate mark (TG gate monogram, dark rounded square with
teal-to-cyan gradient frame) now renders consistently across the three
public brand surfaces. Before this change each surface had drifted to
its own raster:- Landing page (thumbgate.ai): already canonical (header + favicon + og.png)
- Stripe product catalog: ThumbGate Pro and ThumbGate Team each had a
different one-off upload (teal shield / dark gate-with-lightning).
Re-pointed athttps://thumbgate.ai/assets/brand/thumbgate-icon-512.png
via the Stripe API so the checkout surface matches the landing page
and the npm package page. - GitHub repo / npmjs.com: README had no brand image. Now renders the
same canonical 128x128 PNG at the top so github.com visitors and npm
installers see the same mark that renders on the landing page.
public/og.png(already present, already canonical) still needs to be
uploaded to GitHub's Settings -> Social preview separately — GitHub does
not expose that surface via REST or GraphQL, so it can only be uploaded
via the web UI. -
#1196
1ea88ecThanks @IgorGanapolsky! - feat(analytics): deepen buyer loss telemetry and expose loss-analysis reportingCapture first-party buyer behavior on the public landing pages so
ThumbGate can explain lost dollars with evidence instead of anecdotes.- track section views, CTA impressions, page exits, and buyer email
focus/abandon behavior on the homepage and Pro page - aggregate behavioral telemetry into funnel dropoff, inferred causes,
explicit objections, and revenue-opportunity reporting - expose the synthesized loss-analysis view through
/v1/analytics/lossesand keep the OpenAPI surfaces aligned
This release does not claim more revenue by itself. It makes the live
buyer funnel diagnosable once deployed, which closes a major blind spot
in why ThumbGate is not yet converting consistently. - track section views, CTA impressions, page exits, and buyer email
-
#1226
947f12bThanks @IgorGanapolsky! - chore(canonical): thumbgate.ai across public pages and seo-gsdReplaced stale
usethumbgate.comreferences with the canonicalthumbgate.aidomain inpublic/learn.html,public/compare/mem0.html,public/compare/speclock.html,public/llm-context.md, andscripts/seo-gsd.js. PR #1202 attempted this fix and was closed as duplicate of #1201, but #1201 only shipped Multica guide content — the URL replacements never landed. Every canonical link,og:url, schema.orgurl, and llm-context reference on these pages now points at the active domain. -
#1188
6a8b0fbThanks @IgorGanapolsky! - feat(seo): add /guides/chatgpt-ads-trust page and ChatGPT-ads FAQNew SEO/GEO guide page threading the "pre-action gates" thesis
against the ChatGPT ads rollout (CPC bidding went live 2026-04-21
per Digiday; ads test started 2026-02-09 per TechCrunch).Adds a JSON-LD
FAQPageentry on the homepage answering why does
the ChatGPT ads rollout matter to ThumbGate?, and links the new
guide from the ChatGPT GPT section with a "Why ChatGPT ads need
gates" CTA.Canonical URL pinned to
https://thumbgate.ai/guides/chatgpt-ads-trust.
Pre-existing guide files still use the legacyusethumbgate.com
domain that 301-redirects to apex but drops the path — a separate
PR sweeps those. -
#1274
8310236Thanks @IgorGanapolsky! - fix(chatgpt): harden the published GPT feedback-capture repair packetThe ChatGPT GPT setup guide now fails closed when
captureFeedbackis unauthenticated or unavailable: it must say "Not saved in ThumbGate yet" instead of implying a reusable lesson was saved. The GPT Store packet also pins the canonical ThumbGate avatar and records a live audit of the published GPT drift so the wrong icon, stale Action instructions, and Bearer-auth setup issue can be repaired from evidence. -
#1237
4a549e6Thanks @IgorGanapolsky! - Add feedback-derived prompt/workflow evaluation so real thumbs-up/down signals can become reusable eval suites, CLI proof reports, and buyer-ready evidence artifacts. -
#1207
a0517d1Thanks @IgorGanapolsky! - fix(decision-journal): pin clock in metrics test to remove day-boundary flakecomputeDecisionMetricsnow accepts an optionaloptions.nowand threads it intoinitializeDaySeries, so the rolling 14-day window is driven by an injectable clock rather than a freshnew Date()at aggregation time. The metrics test pins both the synthetic event base and the aggregator clock to the same reference timestamp, removing the race where CI crossing UTC midnight between event inserts and aggregation dropped events out of the window and failedmetrics.days.some((day) => day.evaluations > 0). -
#1144
61c65bfThanks @IgorGanapolsky! - Trim additional internal analytics, orchestration, and operational scripts out of the public ThumbGate npm package so the shipped surface stays closer to a thin client. -
#1238
6e98379Thanks @IgorGanapolsky! - feat(eval): expand gate-eval seed set 19→67 cases + wire into CI as regression gateApplying Anthropic's measure-first prompt-eval methodology to ThumbGate's gate layer. The existing
config/evals/agent-safety-eval.jsononly had 19 cases — enough to prove the harness worked, not enough to catch regex drift. This PR widens coverage and turns the eval into a merge-blocker so any constraint change that breaks a case gets caught before ship.Seed expansion (19 → 67 cases):
no-force-push— 9 cases (long/short flag, --force-with-lease, flag-after-branch, extra whitespace, uppercase + 3 negative near-misses for normal push/tags/upstream).no-reset-hard— 7 cases (HEAD~N, origin/main, @{u}, extra whitespace + soft/mixed/plain resets pass).no-rm-rf-root— 8 cases (/, ../, ~, . + node_modules, dist, .cache, single file pass).no-env-in-code— 10 cases (AWS/GitHub/OpenAI/RSA/EC/generic PEM + normal code, short AKIA prefix, doc prose, public key pass).no-skip-hooks— 6 cases (--no-verify on commit/amend/push, --no-gpg-sign + normal commit/rebase pass).no-drop-table— 8 cases (TABLE/DATABASE/SCHEMA, lowercase + SELECT/CREATE/TRUNCATE/DROP COLUMN pass).no-sandbox-network— 9 cases (curl/wget/fetch/net.connect/http + safe log/math pass + 1 documented regex gap).no-sandbox-fs-escape— 8 cases (/etc, /var, /usr, /home, ../, process.env + safe in-memory/local-require pass).- Generic npm-lint pass case (multi-input tool+content).
2 real regex gaps surfaced by the expanded coverage (tracked as follow-ups, not fixed here — scope discipline):
no-env-in-codedoes not catch OpenAI'ssk-proj-<alnum>{20+}format because the embedded dash breaks the[a-zA-Z0-9]{20,}run. Pinned asopenai-project-key-gap-passesso future tightening flips the expectation visibly.no-sandbox-networkrequires whitespace afterhttp/fetch, so packed calls likehttp.request(opts)andfetch('...')slip through. Pinned assandbox-http-dot-request-gap-passesandsandbox-fetch-no-space-gap-passes.
CI regression gate:
- New npm script
gate-eval:cirunsscripts/gate-eval.js runwhich exits non-zero on any case failure. - Added step in
.github/workflows/ci.ymlimmediately afternpm test— any constraint change inconfig/specs/*.jsonthat flips a previously-passing case (e.g. widens a deny regex and starts catching a "safe" case) will block merge until the eval JSON is consciously updated in the same PR.
Net effect: every PR now has to take explicit responsibility for changes to gate behavior. No more silent regex drift.
-
#1206
02fc119Thanks @IgorGanapolsky! - marketing(gcp-mcp): Google Cloud Next 2026 piggyback — Agentic Data Cloud guardrailsAdds
/guides/gcp-mcp-guardrailsSEO landing, four platform posts (LinkedIn, Reddit r/ClaudeAI, Bluesky, Threads) underdocs/marketing/gcp-mcp/, and a Google Data Agent Kit compatibility card on the landing page. Captures the 24-hour news-window audience from Google's April 22 Agentic Data Cloud announcement by positioning ThumbGate as the feedback-driven enforcement layer that IAM and VPC Service Controls cannot represent. No new adapter — the Data Agent Kit drops into Claude Code, Codex, Gemini CLI, and VS Code, all first-class-supported by ThumbGate. -
#1190
ce688deThanks @IgorGanapolsky! - chore(brand): add 1280x640 GitHub social preview assetAdd
public/assets/brand/github-social-preview.pngat GitHub's
1280x640 spec, rendered from the samethumbgate-icon-512.png
that Stripe product thumbnails and the homepage og.png reference.
One canonical visual identity across marketing, checkout, and the
repo social preview.Upload is a manual follow-up: Settings → General → Social preview.
GitHub's REST and GraphQL APIs do not expose an upload endpoint
for this field. -
#1271
19f3b8eThanks @IgorGanapolsky! - docs(gpt-store): sharpen GPT listing copy for discoveryThe live GPT listing had 3 conversations — not a product problem, a discovery problem. Description was jargon-heavy ("proof-backed Reliability Gateway workflows") and conversation starters buried the pain behind branded terminology.
New short/full descriptions lead with the named pain ("Stop your AI agent from repeating mistakes") and starters match what developers type mid-frustration. Also adds an ACTION REQUIRED banner reminding the operator that the live listing needs a publish bump in GPT Builder for updated copy to appear.
Version-metadata test assertions updated to match the new copy (starter text + short description).
-
#1191
9bda185Thanks @IgorGanapolsky! - fix(guides): canonicalize guide pages to thumbgate.aiRewrite
og:url,<link rel="canonical">, and JSON-LD
url/mainEntityOfPage/publisher.urlon the remaining 11 guide
pages fromhttps://usethumbgate.comtohttps://thumbgate.ai.The legacy
usethumbgate.comhost 301-redirects tothumbgate.aibut
drops the path, so Google saw every/guides/<slug>canonicalize to
the bare apex and collapsed the topical signal across all guides into
a single URL. Matches the chatgpt-ads-trust.html fix shipped in #1188. -
Add high-ROI agent operating-system planners for workspace routines, data-table agents, code-mode MCP, hybrid supervisors, graph knowledge layers, audit traces, inference caching, verifier scoring, and synthetic-data provenance gates.
-
#1239
1a24251Thanks @IgorGanapolsky! - feat(lesson-inference): XML-tagged Claude prompt + 5 multishot exemplarsApplies Anthropic's prompt-engineering playbook (ref: Prompt Engineering course) to the LLM lesson-extraction prompt in
scripts/lesson-inference.js. This is PR 2 of the high-ROI eval sequence (PR 1 was gate-eval seed expansion).Why this prompt specifically:
inferStructuredLessonLLMcalls Claude with a strict-JSON output contract. It hits exactly the three failure modes that XML tags + multishot exemplars are designed to fix:- Model occasionally wraps JSON in code fences despite instructions → tightened with explicit
<guidelines>clause +no code fencesprohibition. - Plain-text
Signal: positive/Conversation:headers compete with the conversation content itself for the model's attention → replaced with scoped<signal>,<user_context>,<conversation_window>tags. - Schema description without exemplars means the model has to synthesize shape from an abstract spec → replaced with 5 concrete
<example>blocks drawn from real ThumbGate incident classes.
What changed:
LLM_LESSON_SYSTEM_PROMPTrebuilt with<task>,<output_schema>,<guidelines>,<examples>section tags. Schema enum values moved to explicit pipe-delimited unions (<debugging|implementation|question|error-report|constraint>).- New
LLM_LESSON_MULTISHOT_EXAMPLESconstant — 5 exemplars covering: Edit-before-Read, force-push-to-main, deploy-verification, mock-to-live-in-tests, regression-test-pinning. Each exemplar is a{signal, conversationWindow, output}triple;outputis the exact JSON the model should emit. - New
renderMultishotExamplesForPrompt()renders the exemplar set as<example><signal>…</signal><conversation_window>…</conversation_window><output>{…}</output></example>blocks, then inlines them into the system prompt. - New
buildLessonUserPrompt({signal, context, windowText})wraps the user-side content in<signal>,<user_context>(optional),<conversation_window>tags.inferStructuredLessonLLMnow calls this helper, so the caller'swindowTextnever competes with header text for attention. - Signal normalization preserved:
positive/up→positive;negative/down→negative.
New regression tests (
tests/lesson-prompt-shape.test.js, 9 cases):- Every XML section tag (
<task>,<output_schema>,<guidelines>,<examples>) is balanced and correctly ordered. - Every schema enum value (
ALLOWED_TRIGGER_TYPES,ALLOWED_ACTION_TYPES,ALLOWED_SCOPES) appears in the prompt — accidental removal surfaces instantly. - Multishot exemplar count pinned at 5; must cover both
positiveandnegativesignals. - Every exemplar
outputis schema-valid JSON (trigger.type, action.type, scope enum checks; confidence in [0,1]; non-empty string tags). - Rendered
<example>block extracts cleanly via a naive regex parser and round-trips through JSON.parse back to the source exemplar object. buildLessonUserPromptemits expected XML structure, normalizes signals, omits<user_context>when not provided.- System prompt contains explicit "no code fences / no prose" prohibitions.
What this does NOT change:
- No behavior change in
createLesson,extractTrigger,extractAction,extractToolCalls, or any of the deterministic lesson-building pipeline. Those stay regex-driven and tested by the existing 30-casetests/lesson-inference.test.jssuite (still green). - No measurement of the actual Claude-response quality improvement. That requires a lesson-eval suite analogous to
config/evals/agent-safety-eval.jsonplus live API calls — queued as follow-up (feat/lesson-eval-suite). Today's PR ships the prompt upgrade and the shape-regression guard; quality measurement is the next loop.
Follow-up (not in this PR):
feat/lesson-eval-suite— curate 30+ (signal, conversation_window, expected_lesson) tuples from.claude/memory/feedback/lessons-index.jsonland wire intoscripts/gate-eval.jsas a live A/B suite that compares the old prompt vs the new prompt on the same conversation windows.
- Model occasionally wraps JSON in code fences despite instructions → tightened with explicit
-
#1185
a3952e2Thanks @IgorGanapolsky! - Refresh the public marketing surface with orchestration-vs-enforcement positioning, plus new buyer workflow pages for platform teams and regulated workflows. -
#1153
b9d7f2cThanks @IgorGanapolsky! - fix(mcp): lazy-load lesson search private boundaryMove the remaining direct lesson-search import in the MCP stdio adapter
behind the private module loader. This keeps the hosted/private runtime
behavior unchanged while letting the public shell return the standard
private_coreavailability payload if lesson search is extracted out of
the public package.This pins the boundary in two ways:
search_lessonsnow resolves through the MCP private-module loader.- MCP tests cover the unavailable-module path for lesson search along
with the existing private-core tool matrix.
-
#1153
b9d7f2cThanks @IgorGanapolsky! - fix(mcp): lazy-load semantic and lesson-inference private boundariesMove the remaining direct semantic-layer and lesson-inference imports in
the MCP stdio adapter behind the existing private-module loader. The
public adapter now returns the standardprivate_coreavailability
payload when those modules are absent instead of hard-requiring them at
module load time.This keeps the public shell compatible with the current runtime while
making the next extraction cut safer:get_business_metricsanddescribe_semantic_entitynow route
through the semantic-layer private boundary.context_stuff_lessonsnow routes through the lesson-inference
private boundary.- MCP tests pin both the loaded and unavailable paths so the public
shell can shed these modules without breaking the adapter contract.
-
#1201
e04c2b5Thanks @IgorGanapolsky! - marketing(multica): positioning play for self-hosted agent orchestrationAdds
/guides/multica-thumbgate-setupSEO landing page and four platform posts (LinkedIn, Reddit r/ClaudeAI, Bluesky, Threads) underdocs/marketing/multica/. Captures the self-hosted-agent-orchestration audience (Multica + Claude Code + autopilot users) by positioning ThumbGate as the enforcement layer their autopilot setup is missing. No new adapter — Multica runs first-class-supported terminal agents (Claude Code, OpenCode) that ThumbGate already integrates with. -
#1270
8770d0cThanks @IgorGanapolsky! - fix(operational-dashboard): match operational-summary's loud-failure behavior and full operator-key chainoperational-dashboard.jswas inconsistent withoperational-summary.jsin two ways:-
It resolved only
THUMBGATE_API_KEY, missing theTHUMBGATE_OPERATOR_KEYenv var and~/.config/thumbgate/operator.jsonfile paths that the rest of the CLI uses. This causednorth-starto silently fall back to local data when the operator key was configured correctly forcfo. -
On 401/403 it caught the error and returned empty local dashboard data, mirroring the same silent-$0 bug just fixed in
operational-summary.js.
Both are now aligned: hosted config uses the shared
loadOperatorConfig()chain, and 401/403 throwhosted_dashboard_unauthorized. Non-auth failures still fall back but tagsource: 'local-unverified'withhostedStatusso the CLI can flag unverified data. -
-
#1162
252b648Thanks @IgorGanapolsky! - fix(brand): regenerate public/og.png to match Stripe product iconSocial card previews (LinkedIn, Twitter, iMessage) were serving the
old legacy og.png while Stripe product pages used the canonical
thumbgate-icon-512.png. CEO flagged the mismatch after a LinkedIn
link preview showed the old wordmark banner instead of the current
brand mark.Regenerate
public/og.pngat the standard 1200×630 social-card
aspect, centered on the brand darksrgb(6,16,21)background, using
the exact samethumbgate-icon-512.pngthat Stripe product images
point at. One canonical visual identity across the marketing surface
and the checkout surface.No HTML changes — every page that referenced
/og.pnginherits the
new card automatically as social-platform caches refresh. -
#1189
3b2f8baThanks @IgorGanapolsky! - Fix three post-everywhere dispatcher contract mismatches discovered live
2026-04-22 during the ChatGPT CPC ads campaign:postToLinkedIncalledlinkedin.publishPost({text}); the module exports
publishTextPost(token, personUrn, text).postToThreadscalledthreads.publishPost({text}); no such export (real
entry ispostTextThread({text, token, userId})).postToBlueskycalledzernio.publishPost({text, platform}); the real
signature ispublishPost(content, platforms[], options)withaccountId
required on each platform entry.
All three now route through
zernio.publishToAllPlatforms(content, {platforms:[<name>]})— single code path, account discovery handled by
Zernio. Contract tests intests/post-everywhere-channels.test.jsspy on
publishToAllPlatformsand pin the call shape so this bug class cannot land
again. -
#1153
b9d7f2cThanks @IgorGanapolsky! - Keep the public ThumbGate server package resilient when private orchestration modules are absent by lazy-loading intent routing, handoff, hosted-job, and workflow-sprint surfaces instead of shipping them in the npm tarball. -
#1153
b9d7f2cThanks @IgorGanapolsky! - Keep the public ThumbGate package resilient when private MCP intelligence modules are absent by lazy-loading org dashboard and reflector surfaces instead of shipping them in the npm tarball. -
#1132
0b97f19Thanks @IgorGanapolsky! - docs(directives): persist Product Architecture Split to CLAUDE.md / AGENTS.md / GEMINI.mdCodify the two-repo product boundary on the three canonical directive
files so future sessions — across Claude, Codex, and Gemini — don't
drift the public shell back toward proprietary intelligence surfaces.- Public shell (
IgorGanapolsky/ThumbGate, npmthumbgate): CLI,
hook installer, adapter configs, local gate runner, public schemas,
marketing. Thin by design. - Private core (
IgorGanapolsky/ThumbGate-Core): ranking, policy
synthesis, orchestration, billing intelligence, org visibility,
licensed exports. Not published to npm, not required by public CI.
Boundary rules: no re-expansion, wire protocol only, independent CI,
dedicated worktrees, and no "split complete" claim without measurable
deltas. Violation triggers (direct Core imports, public README
describing Core-only features, Core API keys in public CI, Core as
public runtime dependency) block merge.No runtime change — docs only.
- Public shell (
-
#1157
29c51b9Thanks @IgorGanapolsky! - test(boundary): add public-core-boundary regression testCLAUDE.md / AGENTS.md / GEMINI.md mandate a regression test at
tests/public-core-boundary.test.jsto pin fixes that preserve the
Product Architecture Split. Until now this file did not exist on main,
so each "split complete" claim was unverifiable.The test asserts three directive-codified violation triggers:
- No packaged JS/TS file imports
thumbgate-core,@thumbgate/core,
or../ThumbGate-Core. Public code must talk to Core over a wire
protocol, never directrequire. package.jsondoes not list Core independencies,
peerDependencies, oroptionalDependencies.- The npm bundle file count stays below a ceiling (260 currently, with
~50-file headroom over today's 212) to catch silent re-expansion.
All three pass against the current public shell. This test is the
canonical home for future boundary fixes. - No packaged JS/TS file imports
-
#1133
a419771Thanks @IgorGanapolsky! - Keep the public ThumbGate package boundary thin by removing non-runtime workflow, tracing, and sales pipeline scripts from the published tarball. -
#1140
d675466Thanks @IgorGanapolsky! - Keep the public ThumbGate package boundary aligned with ThumbGate-Core by
loading private-core modules optionally in the public shell, and update
the Pro CLI verification to reflect the current private-core split. -
#1138
cbf8c25Thanks @IgorGanapolsky! - Treat pending changesets as an audited no-op path in the npm publish guard so main no longer fails when release-relevant content lands ahead of the next versioned publish. -
#1155
06a8e25Thanks @IgorGanapolsky! - test(reflector-agent): isolate from developer feedback DBThe
reflector-agent.test.jsunit tests callcheckRecurrence, which
transitively readsmemory-log.jsonlunder the resolved feedback dir.
On developer machines with a populated lesson DB, assertions that
expect zero matches (severity: 'info',recurrence.count: 0) flip
to'warning'/1because real recurring-mistake memories leak in.Pin
THUMBGATE_FEEDBACK_DIRto a fresh emptymkdtempSyncdir for the
lifetime of the file, and restore the prior value in anafterhook.
This lets the full verification chain run head-to-tail without one
stray test stopping the&&chain.No runtime change. Tests only.
-
#1233
fd01a68Thanks @IgorGanapolsky! - Replace customer-facing Pre-Action Gates language with Pre-Action Checks across public docs, package metadata, plugin manifests, and marketing surfaces. -
#1173
019e3a3Thanks @IgorGanapolsky! - Alignscripts/social-reply-monitor.jsandscripts/social-analytics/poll-all.js
with the CLAUDE.md X/Twitter retirement (2026-04-20). The reply monitor's
checkXRepliesbranch (plus itscollectXSearchCandidates,
isRevenueRelevantXTweet,buildOwnedConversationQuery, andDEFAULT_X_HANDLE
helpers) has been removed — the default platform list is now['reddit', 'linkedin'].
LEGACY_POLLERSno longer contains thexentry, andscripts/social-analytics/pollers/x.js
andscripts/social-analytics/publishers/x.jshave been deleted. The
social:poll:xnpm script has been removed. Tests in
tests/social-reply-monitor.test.js,tests/zernio-canonical-pollers.test.js,
andtests/social-analytics.test.jsare pinned to the new surface. -
#1268
377385eThanks @IgorGanapolsky! - fix(operational-summary): throw on 401/403 instead of silently falling back to empty local ledgerThe hosted billing summary client used a
try { hosted } catch { local }pattern that swallowed auth failures. When the operator key expired, the CLI reported $0.00 revenue even though Stripe had real charges — because the local ledger was empty and the 401 was caught silently.Now 401/403 throw
hosted_summary_unauthorizedwith an actionable message (re-auth the operator key). Non-auth failures (503, network) still fall back to local, but the result is taggedsource: 'local-unverified'withhostedStatusso downstream consumers can distinguish verified from unverified revenue. -
#1199
84d5d56Thanks @IgorGanapolsky! - marketing(roo-sunset): Cline-migration campaign + SEO guideAdds
docs/marketing/roo-sunset/copy for LinkedIn / Reddit r/ClaudeAI / Bluesky / Threads (all four live via Zernio 2026-04-22) andpublic/guides/roo-code-alternative-cline.htmlas the SEO landing for the Roo sunset narrative. Pairs with the new Cline adapter to convert Roo's 2026-05-15 shutdown into ThumbGate installs. -
#1259
ad62ce7Thanks @IgorGanapolsky! - Make eval fixtures scanner-safe by replacing secret-shaped committed test data with runtime-expanded placeholders, and add regression coverage to prevent future GitGuardian-style false positives. -
#1272
6d5b82fThanks @IgorGanapolsky! - fix(pricing): correct stale $99/seat Team price in .well-known/llms.txt and extend parity guardAI crawlers reading
.well-known/llms.txtwere being served the retired$99/seat/moTeam anchor. The canonical anchor perdocs/COMMERCIAL_TRUTH.mdhas been$49/seat/mo with a 3-seat minimumsince mid-April 2026; every HTML surface, server-side constant (TEAM_MONTHLY_PRICE_DOLLARS), and README already uses $49. The llms.txt leak was the last unguarded public surface.Also extends
tests/public-package-parity.test.jsto scan.well-known/text surfaces in addition to HTML, so this class of leak is caught in CI next time. -
#1231
256450aThanks @IgorGanapolsky! - feat(billing): differentiate ThumbGate Free/Pro/Team with tier-specific product iconsCEO flagged that the Stripe product catalog renders "ThumbGate Team" and "ThumbGate Pro" with the same icon. Root cause:
scripts/billing.jsalways shippedthumbgate-icon-512.pnginproduct_data.imagesregardless of plan, so Stripe had no way to draw them differently.- Added
public/assets/brand/thumbgate-mark-{pro,team}.svgand rendered 512×512 PNGs. Pro adds a gold PRO ribbon to the upper-right; Team adds a violet pill with three stacked member dots. The core TG gate glyph is unchanged so cross-surface brand continuity holds. - Introduced
resolveTierIconUrl(planId, appOrigin)inscripts/billing.js;buildCheckoutProductDatanow acceptsplanIdand picks the right icon per plan. - Added
scripts/stripe-sync-product-images.js(idempotent) to patch theimagesfield on existing dashboard Products so already-created Team/Pro rows stop rendering as twins. Must run post-deploy once the PNGs are live on the public shell. - Regression test in
tests/billing.test.jspins three distinct URLs for free/pro/team checkout payloads;tests/public-static-assets.test.jsconfirms the public shell serves the two new PNGs.
Follow-up (not in this PR): the core TG monogram still has no thumb silhouette despite the product name. Separate design session to consider integrating the thumb gesture into the primary mark.
- Added
-
#1273
f8f9570Thanks @IgorGanapolsky! - Add a managed-model candidate catalog and CLI planner so ThumbGate can rank and benchmark new providers like Tinker Kimi K2.6 and Qwen3.6 against real gate-eval, prompt-eval, and ThumbGate Bench workflows before routing production traffic. -
#1125
856b818Thanks @IgorGanapolsky! - Add AI recommendation visibility guides for topical presence and relational knowledge, and update touched marketing links to use the landing site at usethumbgate.com. -
#1277
57a465fThanks @IgorGanapolsky! - fix(gates): harden GitHub Actions workflow dispatch decisionsgh workflow runis now classified as a governed high-risk action. Decision evaluation requires workflow-dispatch evidence for environment, workflow file, ref, HEAD SHA, and expected job, blocks mismatches before execution, and returns deliberation/consistency-check instructions for high-risk actions.The public repository was also scrubbed of obsolete project-specific proof lanes and source comments so ThumbGate no longer carries unrelated customer/repo names in tracked files.
-
#1159
6fd61b6Thanks @IgorGanapolsky! - Route LinkedIn and Threads publishing through Zernio whenZERNIO_API_KEYis
set, collapsing three token rotations (LinkedIn, Threads, Bluesky) to a single
Zernio OAuth bundle. Direct-API publishers remain the fallback when the key is
absent and can be forced back on withTHUMBGATE_USE_DIRECT_PUBLISHERS=1
(emergency escape parallel toTHUMBGATE_USE_DIRECT_POLLERS=1for analytics).
Reddit, Instagram, YouTube, Dev.to, and TikTok stay on direct-API because
Zernio cannot match their content shapes (subreddit+title, media, video,
articles).
Verification Standard
- Publish only runs from
mainafter version sync, tests, and runtime proof pass. - The npm package is smoke-tested after publish by installing
thumbgate@VERSIONin a clean runtime. - GitHub Release notes are generated from Changesets, not only GitHub auto-generated PR titles.
Weekly OSS security release digest.
The CVE patches and breaking changes that affected production tools this week. One email, every Sunday.
No spam, unsubscribe anytime.
Share this release
About IgorGanapolsky/mcp-memory-gateway
Pre-action gates that prevent AI coding agents from repeating known mistakes. Captures explicit feedback, auto-promotes failures into prevention rules, and enforces them via hooks.
Related context
Beta — feedback welcome: [email protected]