chore: final public-repo hygiene — remove internal process, counsel work product, and commercial strategy - #166
Conversation
…strategy Final public-repo hygiene pass. Four documents leave the public core repo; each already lives in ResonantIQ/helpthread-internal (private). Removed: - .claude/rules/delegation-ladder.md — internal AI tooling operating policy. Not product documentation; describes how work is produced, not what Helpthread is. The corresponding CLAUDE.md import and the subagent-model line go with it. - legal/counsel-review-memo.md — work product prepared for outside counsel. Publishing it forfeits any privilege posture and publicly enumerates open weaknesses in the project's own license drafts. - specs/modules/catalog.md — the free-vs-paid line and paid module catalog. Commercial strategy. - specs/modules/marketplace-v1.md — Stripe schema, license-key mechanism, and refund/dispute handling, including the statement that per-deployment scoping has no technical control. Commercial distribution mechanics. Also narrowed the .coderabbit.yaml header comment, which disclosed plan tier, review-budget state, and that a passing status check can mean a skipped review. Inbound references in nine documents were rewritten to keep the substantive claim without pointing at a removed path. No relative markdown link in the repo is broken. The public repo keeps everything a module author or operator needs: the module substrate spec, the module API exception, the commercial module license, the charter, and the architecture and decision records. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Replaces 58 first-name attributions with "the maintainer" in 11 documents. The decisions, dates, and their force are unchanged; only the identifier is. Three legal drafts additionally dropped the line stating that the maintainer "is the reviewing counsel." Those documents already carry, and keep, the accurate statement that they are drafts pending outside counsel review; asserting who is standing in as counsel in the meantime is a disclosure the drafts do not need to make and that a reader could reasonably use against the project. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
Important Review skippedAuto incremental reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Pro Plus Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
📝 WalkthroughWalkthroughThe change removes delegation and module catalog/marketplace specifications, revises repository and legal guidance, updates governance and architecture references, normalizes maintainer attribution, corrects a passkey example, and replaces deployment-specific mailbox examples with generic placeholders. ChangesRepository guidance and module references
Legal policy publication status
Technical specification alignment
Operational example generalization
Estimated code review effort: 3 (Moderate) | ~25 minutes Possibly related PRs
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
The Gmail runbook recorded a live provisioning run verbatim: the Cloud project name, the Pub/Sub topic and subscription paths, the push service-account address, the Supabase project ref, the Vercel project and team, the production hostname, and the mailbox the desk answers on. None of it is secret, and all of it together is a targeting sheet for social engineering against that desk. The "As deployed" block becomes "The shape of a completed provisioning run" — placeholder values with the byte-match constraints called out, which is the part an operator following the runbook actually needs. Nothing procedural changed. The same real hostnames and mailbox appeared in three other specs; genericized there too, since scrubbing only the runbook would leave the values published anyway. The trademark policy's contact address is deliberately public and stays. CLAUDE.md's ecosystem list no longer names the internal tool or a person who reads it. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
The four legal documents were published as drafts that announced their own unreviewed status: DRAFT in the titles, status banners naming the review that had not happened, launch gates written as counsel deadlines, and a "Notes to counsel" section at the foot of each. A reader looking for Helpthread's licensing terms found a work-in-progress instead of an answer. They now read as what they are: the project's terms. Removed from all four are the DRAFT titles, the status and gate banners, and the counsel-notes sections. Every open legal question those sections held is preserved, in more detail than the documents carried, in HT-104 through HT-109. The Module API Exception keeps one operative line, because its status is a fact about the grant rather than a disclosure about process: an AGPL-3.0 §7 additional permission takes effect when it is appended to LICENSE, and it has not been appended. Publishing it as though it were in force would grant permissions the project has not decided to grant, and a granted permission cannot be withdrawn from copies already conveyed. legal/README.md gains a matching "What is and is not in force" section in place of its counsel-deadline list. Nothing operative changed in any of the four. The grant text, the license terms, the trademark rules, and the provenance commitments are byte-for-byte what they were. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
@coderabbitai review |
✅ Action performedReview finished.
|
There was a problem hiding this comment.
Actionable comments posted: 4
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
legal/provenance-policy.md (1)
124-128: 🔒 Security & Privacy | 🟡 Minor | ⚡ Quick winRemove the remaining internal-counsel process disclosure.
Section 8 still says AI provenance risk is assessed and managed under internal counsel review. Keep the public provenance commitment, but move this internal reviewer/process detail to the private repository.
🤖 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 `@legal/provenance-policy.md` around lines 124 - 128, Remove the internal counsel review process disclosure from the “AI-assisted development” section while preserving the public commitment regarding AI provenance risk and management. Keep only externally appropriate provenance language in this document and move the removed reviewer/process detail to the private repository.
🤖 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 `@docs/history/CHARTER-v1.md`:
- Line 53: Update the actor-model paragraph to use the mandated Agent/Assistant
vocabulary consistently: refer to human staff as Agents and AI actors as
Assistants, including the definitions at the end, while preserving the existing
schema and workflow descriptions.
- Around line 45-47: Remove references to the deleted module catalog from the
charter passages around the module extension model, including the references at
the amended paragraph and the additional affected sections. Replace them with
the surviving module-substrate/legal documentation or concise self-contained
wording, without changing the stated licensing and runtime behavior.
- Around line 45-47: Replace the detailed managed-hosting amendment and related
marketplace implementation details in the charter with a brief high-level
historical decision summary. Remove references to hosted versus self-hosted
provisioning, artifact identity, license and provisioning trust domains, runtime
behavior, and unresolved commercial mechanics while preserving only the
architectural decision that extensions use build-time modules and typed
hooks/webhooks.
In `@specs/auth/agents-and-auth.md`:
- Around line 533-540: Update the “Per-Agent mailbox scoping (§3.4)” decision
bullet to state that mailbox grants and the Permissions UI are included in this
migration, while conversation-visibility enforcement remains deferred. Remove
the conflicting “no scoping behavior or UI” wording and preserve the confirmed
decision context.
---
Outside diff comments:
In `@legal/provenance-policy.md`:
- Around line 124-128: Remove the internal counsel review process disclosure
from the “AI-assisted development” section while preserving the public
commitment regarding AI provenance risk and management. Keep only externally
appropriate provenance language in this document and move the removed
reviewer/process detail to the private repository.
🪄 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: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro Plus
Run ID: 019dc07e-907f-4ef4-b1be-05b631311141
📒 Files selected for processing (22)
.claude/rules/delegation-ladder.md.coderabbit.yamlCLAUDE.mddocs/architecture/README.mddocs/decisions/README.mddocs/history/CHARTER-v1.mdlegal/README.mdlegal/counsel-review-memo.mdlegal/module-api-exception.mdlegal/module-commercial-license.mdlegal/provenance-policy.mdlegal/trademark-policy.mdspecs/auth/agents-and-auth.mdspecs/auth/passkeys.mdspecs/deploy/gmail-inbound-runbook.mdspecs/mail/gmail-push.mdspecs/mail/mailbox-connection.mdspecs/modules/catalog.mdspecs/modules/marketplace-v1.mdspecs/modules/substrate-v1.mdspecs/ui/admin-ia.mdweb/README.md
💤 Files with no reviewable changes (4)
- .claude/rules/delegation-ladder.md
- specs/modules/catalog.md
- specs/modules/marketplace-v1.md
- legal/counsel-review-memo.md
| Serverless kills the traditional runtime plugin-folder model — there's no long-lived filesystem to drop a module into. Helpthread's extension model is designed in from day one along two tracks: **build-time npm modules**, where an operator adds a package and redeploys — the install *is* the Vercel build — and **typed event hooks / webhooks** for integrations that live out-of-process entirely. The plumbing paid modules need (license keys, license-gated distribution, an update channel) is built alongside the modules themselves and exercised through the project's own installs long before a stranger's money touches it — never as a runtime restriction: a license authenticates downloads and updates, and no shipped module ever phones home or stops working when a license lapses (the module catalog, §5). | ||
|
|
||
| **Amended 2026-07-19 (managed hosting):** the *default* install path is no longer the operator redeploying a module themselves — clicking Install in Manage → Modules provisions a Resonant IQ-hosted instance of the module for that deployment, the realization of the hosted convenience services §3 already contemplates. The self-host path (download the versioned tarball, deploy to your own Vercel) remains fully supported as the open-core escape hatch. Both preserve the same invariants without exception: a license is only ever a distribution credential — no runtime license check ships in any module, hosted or self-hosted, and the hosted artifact is byte-identical to the self-host tarball; no module phones home; and a lapsed license never stops running software, even when Resonant IQ is the host. The credential-bearing install/update orchestration lives entirely outside the AGPL core, in a Resonant IQ-operated hosting control plane — the one component that holds both a license key and a per-desk provisioning grant; the core holds neither and never calls the marketplace (`specs/modules/marketplace-v1.md` §3/§5). | ||
| **Amended 2026-07-19 (managed hosting):** the *default* install path is no longer the operator redeploying a module themselves — clicking Install in Manage → Modules provisions a Resonant IQ-hosted instance of the module for that deployment, the realization of the hosted convenience services §3 already contemplates. The self-host path (download the versioned tarball, deploy to your own Vercel) remains fully supported as the open-core escape hatch. Both preserve the same invariants without exception: a license is only ever a distribution credential — no runtime license check ships in any module, hosted or self-hosted, and the hosted artifact is byte-identical to the self-host tarball; no module phones home; and a lapsed license never stops running software, even when Resonant IQ is the host. The credential-bearing install/update orchestration lives entirely outside the AGPL core, in a Resonant IQ-operated hosting control plane — the one component that holds both a license key and a per-desk provisioning grant; the core holds neither and never calls the marketplace (the marketplace spec, §3/§5). |
There was a problem hiding this comment.
🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win
Remove references to the deleted module catalog.
The revised charter still points readers to “the module catalog” and its shipped list. Replace these references with the surviving module-substrate/legal documentation or a self-contained description so public readers are not directed to an unavailable source.
Also applies to: 55-55, 96-96
🤖 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 `@docs/history/CHARTER-v1.md` around lines 45 - 47, Remove references to the
deleted module catalog from the charter passages around the module extension
model, including the references at the amended paragraph and the additional
affected sections. Replace them with the surviving module-substrate/legal
documentation or concise self-contained wording, without changing the stated
licensing and runtime behavior.
🔒 Security & Privacy | 🟠 Major | 🏗️ Heavy lift
Remove marketplace implementation details from the public charter.
These paragraphs still disclose the managed-hosting install path, hosted/self-host artifact identity, license/provisioning trust domains, and unresolved refund/config-export mechanics. That conflicts with the PR objective to remove commercial strategy and marketplace implementation details from the public repository; retain only a high-level historical decision summary here.
Also applies to: 92-95
🤖 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 `@docs/history/CHARTER-v1.md` around lines 45 - 47, Replace the detailed
managed-hosting amendment and related marketplace implementation details in the
charter with a brief high-level historical decision summary. Remove references
to hosted versus self-hosted provisioning, artifact identity, license and
provisioning trust domains, runtime behavior, and unresolved commercial
mechanics while preserving only the architectural decision that extensions use
build-time modules and typed hooks/webhooks.
|
|
||
| The conversation model is **channel-agnostic from day one**. Email is the founding channel — but a conversation and its threads don't care how a message arrived, and the schema never assumes SMTP. Chat/messaging arrives later as a second channel over the same engine (Supabase Realtime is the push transport; a "chat" is a conversation whose threads travel a faster wire), and an embeddable support widget — knowledge-base search, start a conversation, follow the replies, in the tradition of Help Scout's Beacon — is a planned first-party module built on the same public API. Live-chat trappings like presence and typing indicators layer onto that channel per-operator; they are staffing promises more than plumbing. | ||
|
|
||
| The actor model is **AI-ready from day one**. Every thread records what kind of actor authored it — customer, human staff, or AI. AI-authored work supports draft-before-send states, human-approval handoffs, and a full audit trail. Like channels and modules, these are day-one schema shapes, not features: they cost a column now and a migration crisis later. Vocabulary, fixed here to prevent permanent confusion: **agents** are human support staff; **assistants** are AI actors. |
There was a problem hiding this comment.
📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win
Use the mandated Agents/Assistants vocabulary.
This rewritten actor-model paragraph labels the actor kinds as human staff and AI, then defines lowercase agents/assistants. Use Agent and Assistant consistently for the public actor vocabulary.
🤖 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 `@docs/history/CHARTER-v1.md` at line 53, Update the actor-model paragraph to
use the mandated Agent/Assistant vocabulary consistently: refer to human staff
as Agents and AI actors as Assistants, including the definitions at the end,
while preserving the existing schema and workflow descriptions.
Source: Coding guidelines
| ## 12. Decision points for the maintainer (called out, not silently taken) | ||
|
|
||
| 1. **Roles:** Admin + Agent. *(Confirmed.)* | ||
| 2. **First admin:** `/setup` first-run screen, zero-Agents-guarded. *(Confirmed.)* | ||
| 3. **Provisioning:** both — invite-primary (via the core `EmailSender`) + admin-set-password | ||
| fallback. *(Recommended.)* | ||
| 4. **Per-Agent mailbox scoping (§3.4):** model the `agent_mailbox_access` table in this | ||
| migration; no scoping behavior or UI. *(Confirmed — TJ, 2026-07-18.)* | ||
| migration; no scoping behavior or UI. *(Confirmed — maintainer, 2026-07-18.)* |
There was a problem hiding this comment.
🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win
Update the stale mailbox-scoping decision.
This current decision still says “no scoping behavior or UI,” contradicting §3.4’s explicit statement that grants and the Permissions UI ship now; only conversation-visibility enforcement is deferred. Revise the bullet so the spec does not cause implementers to omit the required grant management behavior.
🤖 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 `@specs/auth/agents-and-auth.md` around lines 533 - 540, Update the “Per-Agent
mailbox scoping (§3.4)” decision bullet to state that mailbox grants and the
Permissions UI are included in this migration, while conversation-visibility
enforcement remains deferred. Remove the conflicting “no scoping behavior or UI”
wording and preserve the confirmed decision context.
…angling catalog references Two of four findings were real and are fixed here. The provenance policy's AI-assisted-development section pointed at an internal counsel-review process instead of stating what the reader needs: that the same provenance rules — no copyleft-derived code, license verification, human design and review, DCO sign-off — apply in full to AI-assisted work. The archived charter referred three times to a module catalog that is no longer in the public repository, directing readers at a source they cannot reach. The surrounding claims are now self-contained; nothing normative changed. Two findings were not applied. The actor-vocabulary finding asks for the rule CLAUDE.md currently states, which is itself superseded — the rename went the other way on 2026-07-25, and propagating it is HT-111, not a hygiene edit. The mailbox-scoping contradiction in agents-and-auth §12.4 is real and confirmed, but it is a substantive spec correction rather than a documentation-hygiene fix; it is HT-110. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
Adjudicated all four findings. Two applied in 8df2cef, two declined with reasons. Applied
Declined
@coderabbitai review |
|
I’ll review the updates in 🐇🔎 ✏️ Learnings added
✅ Action performedReview finished.
|
CodeRabbit's finding about dangling module-catalog references applied more broadly than the three lines it could see. The archived charter also pointed at the marketplace spec twice, and three spec passages cited catalog section numbers a public reader cannot look up. References that merely name the catalog as the thing that decided a question are left alone — they attribute a decision rather than direct a reader to a missing file. What is removed is every pointer that promises a document or a section the reader cannot reach. No claim changed. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
…xcerpted An independent adversarial review rated the previous arrangement a blocker: the "not yet in force" banner sat above the exception, and the exception text below it is written as a complete, standalone license addendum. Anyone quoting the "exception text" section — which is the natural thing to quote — carried the grant without the qualifier. The failure that follows is concrete. A module author points at the published text, ships a proprietary combined work in reliance on it, and is out of AGPL compliance because the permission was never appended to LICENSE. The project then inherits a dispute that starts with "your own repository said we could." The notice now sits inside the quoted block, ahead of the grant, and is marked for deletion on adoption. The grant text itself is unchanged. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
…tory The license governed nothing here. It applies to paid modules, which live in their own separate repositories, and its own text says it replaces the placeholder LICENSE in each of those. A proprietary subscription contract sitting in the open-source tree describing artifacts that are not in the tree is noise at best, and at this stage it reads as commercial apparatus arriving before the product it governs. It moves to ResonantIQ/helpthread-internal and, on adoption, into each paid module's own repository. legal/README.md now says only that separately licensed modules carry their own terms elsewhere, which is the fact a reader of this repository needs. The AGPL-3.0 §7 module API exception stays. That one is the opposite case: it modifies this repository's own license grant, so it has to ship with the work — a downstream who receives the core without it receives plain AGPL only. It remains unadopted and says so inside its own quoted text. What this repository now states about licensing is true of this repository: the AGPL-3.0 governs everything in it, and one additional permission is drafted but not in force. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
…them The policy committed the project to specific techniques, in absolute terms, forever. Techniques age. A published commitment to a technique becomes a stick to beat the project with the moment a better one exists, or the moment a single instance departs from it — and the commitment bought nothing that a commitment to the outcome would not have bought. Each method commitment is replaced by the property it was there to produce: - "copyleft codebases are not opened during development" — the outcome is that no copyleft-derived code enters the shipping tree, which the policy already states. How that is achieved is an engineering decision. - "license-verify every third-party dependency at adoption" — the outcome is that every dependency in the tree carries a compatible license, and that one whose license does not resolve does not ship. The timing of the check is not the point. - "every substantive change receives real human design and review before it is merged" — the outcome is that nothing reaches main without review and the maintainer's approval, with the record preserved. How review is performed is explicitly not committed to here. Two legal theories are also removed. The policy asserted that human review is what supports the copyrightability of AI-assisted work under U.S. Copyright Office guidance. That inference — review implies authorship — is contestable, it is not the project's to assert, and the AGPL-enforcement position does not depend on it: copyright claims belong to whoever owns the lines at issue, which section 1 still says. The corresponding item in section 7's list goes with it. The document opens by stating the distinction, so the next reader knows which sentences are commitments and which are description. CLAUDE.md carried a harder form of the same claim and is corrected to match. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
🟢 SAFE TO MERGE
Gates green. No unauthorized decisions — every decision below is quoted to the maintainer.
CodeRabbit: 4 findings — 2 real and fixed, 1 wrong (it applied a vocabulary rule that is itself superseded, HT-111), 1 real but out of scope (HT-110).
GPT-5.2, adversarial pass over the four legal documents, requested separately. This was not Codex — the Codex CLI is authenticated but its account rejects every model, so an OpenAI model was reached through OpenRouter instead. 8 findings: 1 fixed here, 6 routed to counsel tickets HT-104/106/107/112, 1 left for the maintainer to decide (below).
Read the review-coverage note before merging: CodeRabbit's full review ran on
f91c8f7and covered every substantive change in this PR. The one commit since,8df2cef, applies two of CodeRabbit's own findings and nothing else. The confirmation re-review was requested explicitly but CodeRabbit is rate-limited; that pass has not run. The unreviewed delta is the bot's own accepted suggestions.One-way door: four documents leave the public repository. Deleting them here does not remove them from git history — they remain recoverable with
git log -p. If that matters, it needs a history rewrite, which this PR does not do.Decision provenance
What changed
Removed from the public repo. Each is committed to
ResonantIQ/helpthread-internal(private, ResonantIQ org) on branchdocs/initial-helpthread-internal..claude/rules/delegation-ladder.mdlegal/counsel-review-memo.mdspecs/modules/catalog.mdspecs/modules/marketplace-v1.mdThe legal documents now read as published terms. Removed from all four:
DRAFTtitles, status banners announcing a review that had not happened, launch gates written as counsel deadlines, and the "Notes to counsel" section at the foot of each. Nothing operative changed — the grant text, license terms, trademark rules, and provenance commitments are byte-for-byte what they were.The Module API Exception keeps one line, because its status is a fact about the grant rather than a disclosure about process: an AGPL-3.0 §7 additional permission takes effect when appended to
LICENSE, and it has not been appended. Publishing it as though in force would grant permissions irreversibly.Everything the counsel notes held is now tracked, in more detail than the documents carried:
trademarks@resonantiq.appalias, which is published but does not existAlso: 58 first-name attributions across 11 documents become "the maintainer"; the
.coderabbit.yamlheader no longer discloses plan tier, review-budget state, or that a passing check can mean a skipped review; the ecosystem list no longer names an internal tool or a person; the Gmail runbook's live provisioning values (Cloud project, Pub/Sub paths, service account, Supabase ref, Vercel project and team, production hostname, mailbox) become placeholders, with the same values genericized in three other specs that carried them.The open question for the maintainer
The adversarial reviewer flagged that
legal/README.mdstill says the terms of sale are "not yet written," and that the commercial license still says it applies "on adoption" — arguing that published final terms should not advertise unfinished status.That was left unchanged deliberately, because the alternative is worse. The license genuinely depends on a document that does not exist (HT-112), including for its entire-agreement and notices clauses. Removing the disclosure would not close the gap, it would hide it. Recommendation: keep the honest statement, close the gap by writing the terms of sale.
What to check yourself
This PR touches
legal/,CHARTER-v1, andREADMEfiles, so read the changed text rather than taking this summary for it. The four files inlegal/are short now, and they are the project's public terms.Verification
biome check .— exit 0, 282 filestsc --noEmit— exit 0vitest run— 76 files, 1531 tests passed, exit 0gh repo list Helpthread— one repo, public. Zero private repos in the Helpthread org.🤖 Generated with Claude Code