From ad3bdd98f0c3b5cea65664ae9b604f5f2c287849 Mon Sep 17 00:00:00 2001 From: TJ Baker <1617679+zaridan@users.noreply.github.com> Date: Sat, 18 Jul 2026 21:47:57 -0700 Subject: [PATCH 1/4] docs(plugins): module catalog & the open-core line (HT-66) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The canonical free-vs-paid decision doc, from TJ's 2026-07-18 review of the FreeScout official-module inventory (71 modules, public listing — priced-demand data only, no module source observed) against the charter: - Free core = parity + hygiene: everything table-stakes, including features the reference ecosystem paywalls (tags, API/webhooks, KB, dark mode, keyboard shortcuts) and passkey login (WebAuthn) — security hygiene is always free. - Paid = three clusters: Intelligence (draft-reply assistant first; AI subsumes translator/enrichment/learning-spam-filter), Channels & integrations, Enterprise & ops (Enterprise Auth = SSO/SCIM/2FA policy/login audit — the accepted auth paywall, passkeys stay core). - Widget/portal free-with-branding; branding removal paid. - Born-proprietary discipline, zero privileged first-party access, out-of-process preferred shape; build sequence → HT-67 substrate spec. admin-ia.md §2's "decided at ticket grooming" calls resolve to this catalog (all four flagged modules land core-free); cross-referenced. Co-Authored-By: Claude Fable 5 --- specs/plugins/catalog.md | 139 +++++++++++++++++++++++++++++++++++++++ specs/ui/admin-ia.md | 9 ++- 2 files changed, 145 insertions(+), 3 deletions(-) create mode 100644 specs/plugins/catalog.md diff --git a/specs/plugins/catalog.md b/specs/plugins/catalog.md new file mode 100644 index 0000000..cf8b08f --- /dev/null +++ b/specs/plugins/catalog.md @@ -0,0 +1,139 @@ +# Module Catalog & the Open-Core Line + +Status: **accepted** (2026-07-18, TJ — HT-66). This is the canonical free-vs-paid line for +Helpthread functionality. CHARTER.md §3/§4 governs the legal/architectural mechanics; +`specs/ui/admin-ia.md` §2 carries the reference-instance observations this catalog resolves. +Where `admin-ia.md` deferred core-vs-module calls to "ticket grooming," this document is +that decision. + +**Provenance.** The market inventory below derives from FreeScout's public module listing +(freescout.net/modules — 71 official modules, read 2026-07-18) and the black-box +observations already recorded in `admin-ia.md`. It is priced-demand data: a decade of what +self-hosted helpdesk operators actually pay for. No module source code was observed +(CHARTER provenance rules). FreeScout's third-party community marketplace has not yet been +inventoried; revisit at grooming if a gap appears. + +## 1. The line, stated once + +**Free core = parity and hygiene. Paid = intelligence, channels, and enterprise.** + +- Everything a self-hosted helpdesk operator would call table stakes — including features + FreeScout paywalls — ships AGPL-free in core. Security hygiene is always free: + **passkey login (WebAuthn) is core**, deliberately, where the reference ecosystem sells + 2FA. The conventionally accepted auth paywall is enterprise SSO, and that is where ours + sits (§3.3). +- The charter floor applies verbatim: nothing free today gets paywalled retroactively; + monetization adds, never subtracts. +- The line is one-way asymmetric: free → paid never happens; paid → free stays possible. + When a future call is genuinely uncertain, born-proprietary is the reversible choice. +- **Born-proprietary discipline**: a paid module lives in a closed repo from its first + commit and touches core only through public extension points. Nothing intended for the + paid catalog is ever prototyped inside the AGPL tree. +- **Zero privileged first-party access**: any hook a paid module needs ships in the public + plugin API first (charter module boundary). +- **Preferred module shape is out-of-process** — typed events/webhooks plus the public + API — which needs no §7 exception at all. The in-process build-time plugin API is built + only when a module genuinely needs UI presence, and not before a real module hits that + wall. +- Positioning corollary, used deliberately in marketing: tags, the public API + webhooks, + the knowledge base, dark mode, keyboard shortcuts, and passkey-class security are paid + modules in the FreeScout ecosystem and free in Helpthread core. + +## 2. Free core + +### 2.1 Already shipped + +Tags (HT-29) · internal notes (HT-28) · single-Agent assignee, now roster-wide (HT-31, +HT-54) · soft delete (HT-30) · four-state status incl. spam and pending (HT-26) · folder +semantics (open/closed/spam listing) · public API (charter-core, with the MCP server to +follow it) · per-Agent identity, login, team management, mailbox-access grants (HT-54) · +theme/appearance preference (HT-54) · keyboard-shortcuts surface (admin-ia deviation +list) · open-tracking privacy default OFF (HT-32). + +### 2.2 Committed core, built incrementally (priority at grooming) + +Saved replies · custom folders · send & close · satisfaction ratings · basic reports · +basic workflows/automations · global search · basic custom fields (conversations and +customers) · custom mailbox signatures · office hours / auto-reply windows · out of +office · followers · @mentions in notes · snooze-until-a-date (extends `pending`) · +sender time zone · noreply-address warnings and external-image blocking · CSV export · +GDPR-grade hard delete and export (extends soft delete) · extended editor · dark mode +(full surface) · **passkey login** (WebAuthn on the HT-54 session infrastructure) · +knowledge base (charter-core) · notifications matrix (email/browser, per admin-ia). + +The chat channel is core engine work when it arrives (charter §4: a second channel over +the same engine), distinct from any paid trappings layered on it. + +### 2.3 Not ported — obsolete by architecture + +Move/Remove IMAP Message (no IMAP polling) · Faster Search via Meilisearch (search is +Postgres-native) · Auto Login from notification emails · Custom Homepage · Ticket Number +in subject (threading never depends on it; display numbers shipped in HT-27) · Mailbox +Icons · Twitter/X DM integration (API effectively dead). + +## 3. Paid modules — three clusters + +Each entry is born proprietary (closed repo), integrates out-of-process unless noted, and +ships through the marketplace when that phase opens (charter §5). Order within clusters is +rough priority. + +### 3.1 Intelligence (the differentiator; charter-named leading candidates) + +- **Draft-reply assistant** — the first module (§4). Subscribes to inbound events, calls + the operator-configured model with the operator's keys, posts a draft as an assistant + actor; an Agent approves in core UI. Pure out-of-process. +- **Auto-triage** — tagging, routing, priority; same event-driven shape. +- **KB-grounded auto-answers** — depends on the KB and widget; later. +- AI subsumes rather than ports several reference modules: ticket translation, + learning spam filter, customer data enrichment, satisfaction/sentiment analysis become + facets of assistant modules, not standalone products. + +### 3.2 Channels & integrations (the reference ecosystem's biggest paid cluster) + +WhatsApp · Telegram (integration + notifications) · SMS (Twilio-class) · Facebook +Messenger · Slack notifications · Jira · commerce order-context panes +(Shopify/WooCommerce-class) · mobile push (paired with any future mobile surface). +All are out-of-process by nature: a channel adapter feeds the same channel-agnostic +conversation engine; an integration consumes events and the public API. + +### 3.3 Enterprise & ops + +- **Enterprise Auth** — SAML/OIDC SSO, SCIM/directory sync, 2FA *policy enforcement*, + login audit. (Passkeys themselves are core, per §1.) +- **PGP / S-MIME** signing and encryption. +- **Wallboards & advanced analytics** (basic reports stay core). +- **Kanban view** · **time tracking** · **CRM-grade customer management** (basic + customer records and fields stay core). +- **White-labeling** — see §3.4. +- *Possible, deliberately undecided*: an advanced-workflows module above core's basic + automations. Deciding it is deferred; the core/paid seam inside "workflows" gets drawn + when basic automations are specced, not retroactively. + +### 3.4 The white-label pattern + +The embeddable support widget and end-user portal ship **free with Helpthread branding**; +**branding removal is paid**. Every free install is distribution; the pattern is additive +monetization and thus charter-clean (Help Scout's Beacon and the reference ecosystem both +validate it). + +## 4. Build sequence + +1. **HT-67 — plugin substrate v1 spec**: typed event vocabulary, webhook delivery + (registration, signed payloads, retries), assistant-actor API (draft-post, + list-pending, approve/send with audit). Doubles as counsel raw material for the + §7-exception text (HT-5) — the exception gets drafted against a real API, before the + first external contribution. +2. **Core: event emission + webhook delivery** (AGPL — the substrate is always free). +3. **Core: assistant-actor API + draft-review inbox UI** (design-project-first per the + UI-fidelity rule; the schema has been AI-ready since day one). +4. **First module: draft-reply assistant** in a closed repo, dogfooded on the live + Resonant IQ desk. Dogfood installs are a private npm package in the Vercel build — + no marketplace plumbing required to use our own modules. +5. Marketplace plumbing (license keys, registry, update channel) stays deferred to its + charter phase. + +## 5. Changelog + +- **2026-07-18**: initial version (HT-66). Free/paid line decided by TJ from the + FreeScout official-catalog inventory + charter constraints; passkeys-core, + Enterprise-Auth-paid, white-label pattern, and the three paid clusters locked. diff --git a/specs/ui/admin-ia.md b/specs/ui/admin-ia.md index c8d0b37..51fea1b 100644 --- a/specs/ui/admin-ia.md +++ b/specs/ui/admin-ia.md @@ -38,9 +38,10 @@ What this classification means for Helpthread (charter §3 governs): These are honest positioning differentiators: FreeScout charges for them, we don't. - **Their paid list is market signal for OUR marketplace candidates** — Custom Folders, Saved Replies, Send & Close, Satisfaction Ratings are proven willingness-to-pay - features. Core-vs-module for each is decided at ticket grooming; the charter's floor - ("nothing free today gets paywalled retroactively; monetization adds, never subtracts") - applies, and AI-powered modules remain the leading paid candidates. + features. Core-vs-module is now decided: `specs/plugins/catalog.md` (HT-66) is the + canonical line — all four land core-free there; the charter's floor ("nothing free + today gets paywalled retroactively; monetization adds, never subtracts") applies, and + AI-powered modules lead the paid catalog. - **Dashboard (home)** — multi-mailbox card grid: one card per mailbox with folder counts (Unassigned/Mine/Starred/Drafts/Assigned + last-activity dates) and quick actions @@ -91,3 +92,5 @@ What this classification means for Helpthread (charter §3 governs): - **2026-07-18**: initial version from TJ's HT-54 fidelity review (screenshot index + three-scope rule + module caveat). Roadmap tickets for deferred surfaces filed under HT. +- **2026-07-18** (HT-66): §2's open core-vs-module calls resolved by + `specs/plugins/catalog.md`; this doc keeps the observations, that one keeps the line. From 904defafd43c407a6d76569e674cab5076ee23b9 Mon Sep 17 00:00:00 2001 From: TJ Baker <1617679+zaridan@users.noreply.github.com> Date: Sat, 18 Jul 2026 22:22:18 -0700 Subject: [PATCH 2/4] docs(plugins): marketplace-phase additive contract in the catalog (HT-66) Records TJ's rule that dogfood-built infrastructure is sellable without rebuild: runtime credentials vs licenses decoupled permanently (license = distribution credential, no runtime phone-home), dogfooding needs no licensing, module attribution starts in substrate v1, hosted modules are ordinary SaaS billing. Co-Authored-By: Claude Fable 5 --- specs/plugins/catalog.md | 26 +++++++++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/specs/plugins/catalog.md b/specs/plugins/catalog.md index cf8b08f..5b479e4 100644 --- a/specs/plugins/catalog.md +++ b/specs/plugins/catalog.md @@ -132,7 +132,31 @@ validate it). 5. Marketplace plumbing (license keys, registry, update channel) stays deferred to its charter phase. -## 5. Changelog +## 5. Marketplace phase — additive by contract + +The standing rule (TJ, 2026-07-18): **everything built for dogfood must be sellable +without rebuild — the marketplace only ever adds.** What that means concretely, recorded +now so the marketplace design inherits it: + +- **Runtime credentials ≠ licenses.** Modules authenticate with security credentials + (assistant tokens, webhook signing secrets — substrate v1, free core, every module + uses them). A license key is a *distribution* credential: it authenticates registry + download and the update channel. No runtime license check exists in the substrate, + ever — a runtime phone-home inside a self-hosted product is both hostile to the + own-your-data posture and trivially strippable; enforcement in this market is + distribution + updates + support. Revoking a license stops updates; it never breaks a + running helpdesk. +- **Dogfooding needs no licensing** — we are the vendor; our installs are direct + deployments of product-shaped module repos (credentials/env config only, no + first-party special-casing). The dogfooded artifact IS the marketplace artifact. +- **Install bundles come later, attribution starts now**: assistants and webhook + endpoints carry a `module` slug from substrate v1, so marketplace-phase + install/uninstall/health tooling references existing rows rather than retrofitting + identity. +- Modules **we host** as convenience services are ordinary SaaS billing — no special + machinery in the product. + +## 6. Changelog - **2026-07-18**: initial version (HT-66). Free/paid line decided by TJ from the FreeScout official-catalog inventory + charter constraints; passkeys-core, From aa2ec8a924319736e0295068867b79b6aa37bc4c Mon Sep 17 00:00:00 2001 From: TJ Baker <1617679+zaridan@users.noreply.github.com> Date: Sat, 18 Jul 2026 22:27:12 -0700 Subject: [PATCH 3/4] =?UTF-8?q?docs(modules):=20vocabulary=20=E2=80=94=20t?= =?UTF-8?q?he=20artifacts=20are=20Modules,=20never=20plugins=20(HT-66)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit TJ's call, standardizing on the charter's own product noun: specs/plugins/ becomes specs/modules/, "plugin API" wording becomes "module API", and CLAUDE.md's vocabulary section pins the rule. The word "plugin" survives only in the legal phrase "plugin exception" (§7 additional permission). Co-Authored-By: Claude Fable 5 --- CLAUDE.md | 2 ++ specs/{plugins => modules}/catalog.md | 6 +++--- specs/ui/admin-ia.md | 4 ++-- 3 files changed, 7 insertions(+), 5 deletions(-) rename specs/{plugins => modules}/catalog.md (98%) diff --git a/CLAUDE.md b/CLAUDE.md index e5e764c..523205d 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -40,6 +40,8 @@ Adapted in our own words from Andrej Karpathy's observations on LLM coding pitfa **Agents** are human support staff. **Assistants** are AI actors. Never conflate them — in schema, code, docs, or prose. +**Modules** are the extension artifacts operators install (free or paid; TJ, 2026-07-18). Never "plugins" — that word survives only inside the legal phrase *plugin exception* (the AGPL §7 additional permission) and charter quotations. + ## UI fidelity (TJ, 2026-07-12) The Agent Inbox UI's pixel source of truth is the Claude Design prototype — `Helpthread App.dc.html` in the "Helpthread Agent Inbox Design" project (the "Helpthread" design-system project carries the same components). **The dogfood site must match it exactly — the whole designed surface, not a subset.** Design-system files under `web/src/components/ds/` stay verbatim copies; improvements go upstream in the design project first. Any deviation — visual, copy, or interaction — requires TJ's explicit sign-off. Remaining gaps are tracked as the fidelity checklist on [HT-23](https://resonantiq.atlassian.net/browse/HT-23); the ticket is not done until the checklist is. diff --git a/specs/plugins/catalog.md b/specs/modules/catalog.md similarity index 98% rename from specs/plugins/catalog.md rename to specs/modules/catalog.md index 5b479e4..ecdc9f4 100644 --- a/specs/plugins/catalog.md +++ b/specs/modules/catalog.md @@ -30,9 +30,9 @@ inventoried; revisit at grooming if a gap appears. commit and touches core only through public extension points. Nothing intended for the paid catalog is ever prototyped inside the AGPL tree. - **Zero privileged first-party access**: any hook a paid module needs ships in the public - plugin API first (charter module boundary). + module API first (charter module boundary). - **Preferred module shape is out-of-process** — typed events/webhooks plus the public - API — which needs no §7 exception at all. The in-process build-time plugin API is built + API — which needs no §7 exception at all. The in-process build-time module API is built only when a module genuinely needs UI presence, and not before a real module hits that wall. - Positioning corollary, used deliberately in marketing: tags, the public API + webhooks, @@ -118,7 +118,7 @@ validate it). ## 4. Build sequence -1. **HT-67 — plugin substrate v1 spec**: typed event vocabulary, webhook delivery +1. **HT-67 — module substrate v1 spec**: typed event vocabulary, webhook delivery (registration, signed payloads, retries), assistant-actor API (draft-post, list-pending, approve/send with audit). Doubles as counsel raw material for the §7-exception text (HT-5) — the exception gets drafted against a real API, before the diff --git a/specs/ui/admin-ia.md b/specs/ui/admin-ia.md index 51fea1b..b38b584 100644 --- a/specs/ui/admin-ia.md +++ b/specs/ui/admin-ia.md @@ -38,7 +38,7 @@ What this classification means for Helpthread (charter §3 governs): These are honest positioning differentiators: FreeScout charges for them, we don't. - **Their paid list is market signal for OUR marketplace candidates** — Custom Folders, Saved Replies, Send & Close, Satisfaction Ratings are proven willingness-to-pay - features. Core-vs-module is now decided: `specs/plugins/catalog.md` (HT-66) is the + features. Core-vs-module is now decided: `specs/modules/catalog.md` (HT-66) is the canonical line — all four land core-free there; the charter's floor ("nothing free today gets paywalled retroactively; monetization adds, never subtracts") applies, and AI-powered modules lead the paid catalog. @@ -93,4 +93,4 @@ What this classification means for Helpthread (charter §3 governs): - **2026-07-18**: initial version from TJ's HT-54 fidelity review (screenshot index + three-scope rule + module caveat). Roadmap tickets for deferred surfaces filed under HT. - **2026-07-18** (HT-66): §2's open core-vs-module calls resolved by - `specs/plugins/catalog.md`; this doc keeps the observations, that one keeps the line. + `specs/modules/catalog.md`; this doc keeps the observations, that one keeps the line. From e903c86a142f8ab8c8f9e18bc5cd3062db986d25 Mon Sep 17 00:00:00 2001 From: TJ Baker <1617679+zaridan@users.noreply.github.com> Date: Sun, 19 Jul 2026 08:42:59 -0700 Subject: [PATCH 4/4] =?UTF-8?q?docs(rules):=20ladder=20amendment=20?= =?UTF-8?q?=E2=80=94=20finding=20vs=20sign-off,=20tiered=20review=20escala?= =?UTF-8?q?tion=20(TJ)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Mirror sync from the canonical delegation-ladder doc: the reviewer generates findings, the lead adjudicates (that IS the sign-off); default reviewer stays one tier above the author, but sacred-invariant work escalates to a lead-tier reviewer plus a different-vendor pass — earned empirically in the substrate run (disjoint blind spots). Co-Authored-By: Claude Fable 5 --- .claude/rules/delegation-ladder.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.claude/rules/delegation-ladder.md b/.claude/rules/delegation-ladder.md index 8d41e8f..280a565 100644 --- a/.claude/rules/delegation-ladder.md +++ b/.claude/rules/delegation-ladder.md @@ -31,6 +31,8 @@ Pick the lead by how often the session needs Fable-grade judgment — then never ## Principles (all surfaces) - **Review invariant.** Reviewer ≠ author, and reviewer tier ≥ author tier. When the lead authors an artifact itself, the reviewer is a *parallel* agent at the lead's own tier — a Fable lead gets a parallel Fable reviewer, an Opus lead a parallel Opus reviewer — so the review is independent of the author's context. +- **Finding vs. sign-off.** The reviewer *generates adversarial findings*; the lead *adjudicates* them — judges which are real, directs the fixes, spot-checks the result. Adjudication is the sign-off, and it always happens at the lead's tier by construction. "Who reviews" is therefore a question about defect-hunting, never about who approves. +- **Tiered review escalation (TJ, 2026-07-19).** Default reviewer for contained implementation is one tier above the author (Opus for Sonnet work under a Fable lead). Work touching a repo's **sacred invariants** (e.g. mail semantics, auth/security-critical paths, the licensing boundary) escalates to a reviewer at the lead's own tier **plus** an independent different-vendor pass (e.g. Codex). Rationale, earned empirically (Helpthread substrate run, 2026-07-19): every reviewer tier caught real defects, but *different* models caught disjoint ones — a Codex pass found a TOCTOU that both a Sonnet author and an Opus review missed, and a Sonnet author found a spec bug a Fable-tier review had passed. Diversity catches what tier alone doesn't; spend tier where invariants are sacred, spend diversity everywhere it's cheap. - **Verification vs. review litmus.** If the checklist can be written in advance, it's verification — Haiku runs it. If the reviewer has to generate the checklist, it's review — it goes up-ladder. - **Don't-delegate floor.** If writing a self-contained spec costs more than doing the task, the lead does it directly. - **On failure.** One retry with a corrected spec. On a second failure, escalate one tier or the lead absorbs the task. Never re-run a failing agent on an unchanged spec.