Skip to content

chore(docs): write specs and comments for their reader, not as a record of drafting - #188

Merged
zaridan merged 2 commits into
mainfrom
chore/public-doc-voice
Aug 4, 2026
Merged

chore(docs): write specs and comments for their reader, not as a record of drafting#188
zaridan merged 2 commits into
mainfrom
chore/public-doc-voice

Conversation

@zaridan

@zaridan zaridan commented Aug 4, 2026

Copy link
Copy Markdown
Contributor

🟢 SAFE TO MERGE

All 8 gates green, including the full test suite. No behaviour change — comments, spec prose, and test titles only. Three INFERRED items below are style calls, listed for the record rather than blocking.

Review: CodeRabbit reviewed this tree and its findings were adjudicated (see conversation). Its current check reads "Review skipped: incremental reviews are disabled" — a force-push rewrote the commit messages, leaving the tree byte-identical to the version it reviewed. No review coverage was lost, but this check is not a fresh review of this exact head.


The problem

Public documents narrated how they were made, in two forms:

  1. Draft archaeology — "an earlier draft of this section said it would", "the earlier wording overclaimed". A reader has one version and no interest in the others.
  2. Naming the review toolingdraft.3 (2026-07-19, CodeRabbit review, PR #88), // CodeRabbit (Major):, found by adversarial review. That publishes how the work gets reviewed, and it dates instantly.

78 instances across 8 specs and 40 source files.

What changed

Specs. Every instance restated forward. Where a self-correction carried a real argument, the argument stays — passkeys.md §8 now asks "why not log-only across the board?" and answers it. Where it carried none, it's gone.

Two draft-numbered changelogs became dated entries. agents-and-auth.md keeps every substantive change from its seven former entries — mailbox access, the closed status lifecycle, the acting-Agent header rule, the advisory-lock serialization, the hardening list — with PR references retained. passkeys.md collapses to one entry, since none of it has shipped.

Source comments. Attribution dropped, technical content kept:

  • store/mailboxes.ts"Why not tell the operator to disconnect and retry? Because that instruction would be false: markDisconnected only sets status…"
  • providers/inbound-email.ts"Why not return a NormalizedInboundEmail? That puts the parse inside the provider…"
  • mail/gmail-reconcile.ts"Why not just ack? The tempting reasoning is 'the holder will advance the cursor'…"

Ticket and PR references are keptHT-70:, (PR #94). Those are navigable provenance rather than process narration.

.coderabbit.yaml is untouched: a tool's own configuration has to name it.

Two corrections to the specs themselves

Surfaced while rewriting the changelogs, and worth flagging separately because they are content, not style:

  1. agents-and-auth.md decision point 4 recorded "model the table; no scoping behavior or UI" while §3.4 manages real grants with endpoints and a UI. The recorded decision is left intact — a supersession note now points at §3.4.
  2. inbound-ingestion.md §2 had a truncated sentence ("hands attachment ownership to the transport. changes the seam"). Repaired.

Declined

Capitalizing Modules throughout. substrate-v1.md's vocabulary note uses lower-case in prose — "the extension artifacts are modules" — and "module catalog" names an actual document. That would be a repo-wide style change on contested ground, not a hygiene fix.

Decision provenance

Decision — in plain words Source
Audit public docs for this pattern and prevent recurrence Maintainer instruction, 2026-08-03
Sweep the affected specs, then the source comments Maintainer instruction, 2026-08-03
⚠️ INFERRED — ticket and PR references kept while tool names go Mine. The line is navigable-provenance vs. process-narration
⚠️ INFERRED — the replacement wording throughout, and the rewritten changelog structure Mine
⚠️ INFERRED.coderabbit.yaml out of scope; Modules capitalization declined Mine

One-way doors

None. Comment and prose edits, fully reversible. No API, schema, licensing term, or public promise touched.

Verification

typecheck ✅ · web typecheck ✅ · lint ✅ · full test suite ✅ (CI, 14m)

Every source edit is inside a comment except test titles, which are descriptive strings — verified mechanically.

Prevention

A pre-commit hook blocks these patterns, scoped to this organization's repositories. The same history stays useful in private repos and is not blocked there.

@vercel

vercel Bot commented Aug 4, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
helpthread Ready Ready Preview Aug 4, 2026 6:44pm
helpthread-inbox Ready Ready Preview Aug 4, 2026 6:44pm

Request Review

@coderabbitai

coderabbitai Bot commented Aug 4, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

This PR updates authentication and mail specifications, source documentation, comments, and test descriptions. It removes historical review-tool attribution wording and consolidates changelogs. Runtime behavior, public APIs, and test assertions remain unchanged.

Changes

Specification and documentation wording cleanup

Layer / File(s) Summary
Authentication specification clarifications
specs/auth/agents-and-auth.md, specs/auth/passkeys.md
Clarifies WebAuthn storage, passkey classification, challenge creation, RP ID, counter policy, mailbox grants, and Agent access.
Mail and module specification clarifications
specs/mail/*, specs/modules/substrate-v1.md, specs/ui/admin-ia.md, specs/api/agent-inbox-v1.md
Updates mail semantics, retry, concurrency, provider-boundary, classification, changelog, and administrative-scope wording.
Source comments and test-description cleanup
src/**, web/**, scripts/dev-api.ts
Removes review-tool attribution wording and clarifies current behavior in source documentation and test descriptions. No executable logic changes.

Estimated code review effort: 2 (Simple) | ~15 minutes

Possibly related PRs

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Docstring Coverage ✅ Passed Docstring coverage is 86.67% which is sufficient. The required threshold is 80.00%.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately summarizes the removal of drafting and review-history narration from specifications and comments.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch chore/public-doc-voice

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.

❤️ Share

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

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 5

🤖 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 `@specs/auth/agents-and-auth.md`:
- Around line 555-560: Update the consolidated changelog statements around the
passkey migration and agent_mailbox_access so they no longer contradict the
current specification. Either explicitly label the “no schema changes” and
“schema-only” claims as superseded historical statements, or rewrite them to
reflect webauthn_credentials and the managed grant behavior, auto-granting, and
grant endpoints defined in the relevant sections.

In `@src/api/assistants.test.ts`:
- Line 283: Rename the describe block title in the assistant auth failure
containment test to use “Assistant authentication failure containment,”
preserving the test behavior and all other wording.

In `@src/api/drafts.ts`:
- Line 228: Remove review-process narration from all seven changed locations: in
src/api/drafts.ts lines 228, 299, and 370, replace the HT-70 review-fix wording
with direct descriptions of the body-length rule, approval preflight, and
authoritative catch; in src/api/drafts.test.ts lines 516 and 656, remove “review
fix” from the suite titles; in src/api/imap-connect.test.ts line 242, remove
“review fix” from the comment; and in src/api/imap-connect.ts line 155, replace
“until review caught it” with the current authorization invariant. Retain HT or
PR references only as provenance.

In `@src/composition/health.test.ts`:
- Line 492: Remove review-process narration from the comments: in
src/composition/health.test.ts:492 remove “(review, 2026-08-02)”; in
src/db/migrate.ts:1732 retain HT-101 while removing “review of”; in
src/db/migrate.ts:1827 remove “review (2026-07-31)” and state the provenance
violation directly; in src/modules/deploy/vercel-adapter.ts:4 retain HT-119
while removing “design review”; in src/store/imap-watch-state.test.ts:153
replace the review-fix prefix with the lease-token fencing invariant; and in
src/store/mailboxes.test.ts:375 replace the review-fix prefix with the
provider-conflict invariant.

In `@src/store/conversations.ts`:
- Line 870: Remove residual review-process wording from the specified comments
and test titles: in src/store/conversations.ts lines 870-870 and 1759-1759,
replace “review fix” with the direct status-check explanation and remove it
while correcting punctuation before the em dash; in
src/providers/adapters/imap/client.test.ts lines 291-291, remove the dated
review wording and state the shared-flag requirement; in
src/store/conversations.test.ts lines 1833-1833 and 1868-1868, remove “review
fix” from the test titles; and in src/store/imap-watch-state.ts lines 56-56 and
91-91, replace review/date references with the direct lease-fencing and
quarantine invariants.
🪄 Autofix

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: 5082fdbb-8adf-4e79-a140-e3c7a920ff3c

📥 Commits

Reviewing files that changed from the base of the PR and between c8a60dd and 9e1f0ce.

📒 Files selected for processing (41)
  • specs/auth/agents-and-auth.md
  • specs/auth/passkeys.md
  • specs/mail/gmail-push.md
  • specs/mail/mailbox-connection.md
  • specs/mail/sending.md
  • specs/mail/spam-classification.md
  • specs/modules/substrate-v1.md
  • specs/ui/admin-ia.md
  • src/api/assistant-auth.ts
  • src/api/assistants.test.ts
  • src/api/drafts.test.ts
  • src/api/drafts.ts
  • src/api/imap-connect.test.ts
  • src/api/imap-connect.ts
  • src/api/index.test.ts
  • src/api/index.ts
  • src/auth/webauthn-ceremony.ts
  • src/composition/health.test.ts
  • src/composition/health.ts
  • src/db/migrate.ts
  • src/mail/approve-draft.test.ts
  • src/mail/approve-draft.ts
  • src/mail/delivery-worker.test.ts
  • src/mail/message-id.test.ts
  • src/mail/parse.test.ts
  • src/mail/reply-token.test.ts
  • src/mail/send.test.ts
  • src/mail/sender-resolver.test.ts
  • src/mail/thread.test.ts
  • src/modules/deploy/vercel-adapter.ts
  • src/providers/adapters/imap/client.test.ts
  • src/providers/adapters/imap/client.ts
  • src/providers/adapters/smtp/verify.ts
  • src/store/conversations.test.ts
  • src/store/conversations.ts
  • src/store/imap-watch-state.test.ts
  • src/store/imap-watch-state.ts
  • src/store/mailboxes.test.ts
  • src/store/module-installs.ts
  • src/store/webauthn.test.ts
  • src/store/webauthn.ts

Comment thread specs/auth/agents-and-auth.md Outdated
Comment thread src/api/assistants.test.ts Outdated
Comment thread src/api/drafts.ts Outdated
Comment thread src/composition/health.test.ts Outdated
Comment thread src/store/conversations.ts Outdated
@zaridan

zaridan commented Aug 4, 2026

Copy link
Copy Markdown
Contributor Author

Adjudication — 5 findings, all real, all fixed

# Finding Resolution
1 Stale schema claims in agents-and-auth.md's consolidated changelog Fixed — see below
2 assistant should be Assistant in a test title Fixed
3 HT-70 review fix: narration, 7 locations Fixed
4 Residual (review, …) / design review, 6 locations Fixed
5 review fix narration, 7 further locations Fixed

Findings 3–5 were the same defect reported three ways; following them out brought the total to 78 sites.

On finding 1 — two claims in the consolidated entry no longer matched the spec:

  • "agent_mailbox_access is modelled schema-only, no behaviour" — §3.4 is titled "grants managed now, enforcement deferred" and defines auto-granting and grant endpoints. Now states that grants are real managed data, and that what stays deferred is enforcement.
  • "No schema or behaviour in this spec changes", sitting directly after a description of webauthn_credentials. Now reads "Nothing defined by this spec changes — webauthn_credentials is specified in passkeys.md §2.1, not here."

The line drawn: ticket and PR references stay (HT-70:, (PR #94)) as navigable provenance; the review fix framing around them goes.

@coderabbitai

coderabbitai Bot commented Aug 4, 2026

Copy link
Copy Markdown

@zaridan Acknowledged. I will perform a full review of the updated PR.

🐇 ✓


✏️ Learnings added
Learnt from: zaridan
URL: https://github.com/Helpthread/helpthread/pull/188

Timestamp: 2026-08-04T17:33:05.714Z
Learning: For this repository, documentation and source-comment cleanup must remove self-narration patterns such as "review fix", reviewer attribution, tool names, model names, and drafting-history framing. Retain ticket and PR references such as `HT-70`, `HT-101`, and `PR `#94`` when they provide navigable provenance. Preserve `INFERRED` and `DECIDED` markings.

Note: Learnings are effective only in the context of similar code segments. To apply general coding guidelines, please configure review instructions. You can manage existing learnings in the app.

✅ Action performed

Full review finished.


Your included review limit is currently reached under our Fair Usage Limits Policy. This review may still proceed through usage-based billing if eligible. Your next included review will be available in 26 minutes.

@zaridan

zaridan commented Aug 4, 2026

Copy link
Copy Markdown
Contributor Author

Adjudication — second pass

CodeRabbit was rate-limited on the preceding push, so an independent adversarial pass was run in its place and its findings adjudicated below. Disclosed as a substitution: CodeRabbit had not reviewed those commits at the time.

# Finding Resolution
1–2 Stale schema claims in the consolidated changelog Already fixed in a591cda
3 PR references dropped from the consolidated changelog entries Fixed — PR #82, #88, #69, #85 restored
4 28 further sites using uncovered phrasings Fixed
5 Two prose artifacts (orphaned paren; a date made the grammatical subject) Fixed

On finding 4 — the remaining phrasings were "an earlier revision", "the first draft", "originally anticipated", "retracted here", "review round 2", "amended during implementation", "flagged in review", and "used to read". Each is restated forward with its technical lesson intact.

Also surfaced: agents-and-auth.md decision point 4 recorded "no scoping behavior or UI" while §3.4 manages real grants. The recorded decision is left intact; a supersession note points at §3.4.

Deliberately out of scope: docs/decisions/README.md retains one "an earlier revision of this change". A decision log's purpose is recording what was decided and what was rejected — that is content there.

@coderabbitai

coderabbitai Bot commented Aug 4, 2026

Copy link
Copy Markdown

@zaridan I will review the current PR state.

I noted the scope boundary for docs/decisions/README.md: decision logs may retain historical decision and rejection context when that context is substantive content.

🐇 🔍


✏️ Learnings added
Learnt from: zaridan
URL: https://github.com/Helpthread/helpthread/pull/188

Timestamp: 2026-08-04T18:03:38.281Z
Learning: For Helpthread, remove self-narration from source comments and general specification prose, but preserve historical decision and rejection context in `docs/decisions/README.md` when it is substantive decision-log content rather than process narration.

Note: Learnings are effective only in the context of similar code segments. To apply general coding guidelines, please configure review instructions. You can manage existing learnings in the app.

✅ Action performed

Full review finished.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 3

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src/providers/adapters/imap/client.ts (1)

347-352: 📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

Remove the revision-history wording.

The phrase which the previous revision left unguarded describes review history, not current behavior. Keep the comment forward-facing.

Proposed wording
-    // imapflow's own `close()` can throw synchronously on an already-broken connection,
-    // which the previous revision left unguarded (2026-07-31).
+    // imapflow's own `close()` can throw synchronously on an already-broken connection.

This follows the PR objective to remove process narration from source comments.

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

In `@src/providers/adapters/imap/client.ts` around lines 347 - 352, Update the
cleanup comment near the IMAP client close logic to remove the revision-history
phrase “which the previous revision left unguarded.” Keep the explanation
focused on the current behavior: imapflow’s close operation may throw
synchronously on a broken connection and must not let cleanup errors replace the
original outcome.
🤖 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 `@specs/auth/agents-and-auth.md`:
- Around line 600-604: Standardize extension-artifact terminology to “Modules”
across the specified passages: in specs/auth/agents-and-auth.md lines 600-604,
replace “plugin loader” with “Module loader” and lowercase “modules” with
“Modules”; in lines 550-556, use “catalog of Modules” and “marketplace Module”;
apply the same replacements in specs/auth/passkeys.md lines 11-12, update
“module exception” and “third-party modules” to approved “Modules” terminology
in lines 36-40, and change “paid module” to “paid Module” in line 1029.

In `@src/mail/ingest.test.ts`:
- Line 622: Update the test description in the self-echo scenario to refer to
the human support role as “Agent” with the requested capitalization, while
preserving the existing meaning and scenario details. Use “Agent” for the human
support role and reserve “Assistant” for AI actors.

In `@src/mail/parse.test.ts`:
- Line 254: Remove the “Follow-up:” process label from the comments near the
References parsing cases, including the comments at the identified locations,
while preserving the technical explanation about CFWS/comments between IDs.

---

Outside diff comments:
In `@src/providers/adapters/imap/client.ts`:
- Around line 347-352: Update the cleanup comment near the IMAP client close
logic to remove the revision-history phrase “which the previous revision left
unguarded.” Keep the explanation focused on the current behavior: imapflow’s
close operation may throw synchronously on a broken connection and must not let
cleanup errors replace the original outcome.
🪄 Autofix

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: 7de6f81e-810e-45bd-803a-8935f78c0aae

📥 Commits

Reviewing files that changed from the base of the PR and between c8a60dd and 67fbd55.

📒 Files selected for processing (75)
  • scripts/dev-api.ts
  • specs/api/agent-inbox-v1.md
  • specs/auth/agents-and-auth.md
  • specs/auth/passkeys.md
  • specs/mail/gmail-connect.md
  • specs/mail/gmail-push.md
  • specs/mail/inbound-ingestion.md
  • specs/mail/mailbox-connection.md
  • specs/mail/sending.md
  • specs/mail/spam-classification.md
  • specs/modules/substrate-v1.md
  • specs/ui/admin-ia.md
  • src/api/assistant-auth.ts
  • src/api/assistants.test.ts
  • src/api/conversations.ts
  • src/api/drafts.test.ts
  • src/api/drafts.ts
  • src/api/gmail-webhook.test.ts
  • src/api/imap-connect.test.ts
  • src/api/imap-connect.ts
  • src/api/index.test.ts
  • src/api/index.ts
  • src/auth/webauthn-ceremony.ts
  • src/composition/health.test.ts
  • src/composition/health.ts
  • src/composition/root.ts
  • src/db/migrate.test.ts
  • src/db/migrate.ts
  • src/mail/approve-draft.test.ts
  • src/mail/approve-draft.ts
  • src/mail/delivery-worker.test.ts
  • src/mail/delivery-worker.ts
  • src/mail/gmail-disconnect.test.ts
  • src/mail/gmail-disconnect.ts
  • src/mail/gmail-reconcile.test.ts
  • src/mail/gmail-reconcile.ts
  • src/mail/imap-fetch.test.ts
  • src/mail/ingest.test.ts
  • src/mail/ingest.ts
  • src/mail/message-id.test.ts
  • src/mail/parse.test.ts
  • src/mail/reply-token.test.ts
  • src/mail/send.test.ts
  • src/mail/send.ts
  • src/mail/sender-resolver.test.ts
  • src/mail/sender-resolver.ts
  • src/mail/thread.test.ts
  • src/modules/deploy/vercel-adapter.ts
  • src/providers/adapters/gmail/history.test.ts
  • src/providers/adapters/gmail/history.ts
  • src/providers/adapters/imap/client.test.ts
  • src/providers/adapters/imap/client.ts
  • src/providers/adapters/imap/fetch.ts
  • src/providers/adapters/smtp/verify.ts
  • src/providers/email-sender.ts
  • src/providers/inbound-email.ts
  • src/store/conversations.test.ts
  • src/store/conversations.ts
  • src/store/imap-credentials.ts
  • src/store/imap-watch-state.test.ts
  • src/store/imap-watch-state.ts
  • src/store/inbound-deliveries.test.ts
  • src/store/inbound-deliveries.ts
  • src/store/mailboxes.test.ts
  • src/store/mailboxes.ts
  • src/store/module-installs.ts
  • src/store/vercel-connection.ts
  • src/store/webauthn.test.ts
  • src/store/webauthn.ts
  • src/store/webhook-endpoints.ts
  • web/src/app/(shell)/layout.tsx
  • web/src/components/ConnectInboxForm.tsx
  • web/src/components/FolderNav.tsx
  • web/src/components/InboxSettingsShell.tsx
  • web/src/components/TopBar.tsx

Comment on lines +600 to +604
disabled, leaking no status; the §7 boundary claim is scoped to the interface plus a
provider-agnostic schema — not a plugin loader — and adds an identity-service seam so
modules never write core tables directly; invites use the `EmailSender` *transport*,
not `sendReply`, with a distinct `hti.` token prefix; email is immutable in v1; and the
bearer-token-bypasses-role-checks boundary is stated plainly.

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

Use Modules for extension artifacts.

These changed passages use inconsistent extension-artifact terminology. Replace the lower-case and alternate terms with Modules terminology.

  • specs/auth/agents-and-auth.md#L600-L604: replace plugin loader with Module loader and modules with Modules.
  • specs/auth/agents-and-auth.md#L550-L556: replace module catalog and marketplace module with catalog of Modules and marketplace Module.
  • specs/auth/passkeys.md#L11-L12: replace module catalog and marketplace module with catalog of Modules and marketplace Module.
  • specs/auth/passkeys.md#L36-L40: replace module exception and third-party modules with the approved Modules terminology.
  • specs/auth/passkeys.md#L1029-L1029: replace paid module with paid Module.
📍 Affects 2 files
  • specs/auth/agents-and-auth.md#L600-L604 (this comment)
  • specs/auth/agents-and-auth.md#L550-L556
  • specs/auth/passkeys.md#L11-L12
  • specs/auth/passkeys.md#L36-L40
  • specs/auth/passkeys.md#L1029-L1029
🤖 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 600 - 604, Standardize
extension-artifact terminology to “Modules” across the specified passages: in
specs/auth/agents-and-auth.md lines 600-604, replace “plugin loader” with
“Module loader” and lowercase “modules” with “Modules”; in lines 550-556, use
“catalog of Modules” and “marketplace Module”; apply the same replacements in
specs/auth/passkeys.md lines 11-12, update “module exception” and “third-party
modules” to approved “Modules” terminology in lines 36-40, and change “paid
module” to “paid Module” in line 1029.

Source: Coding guidelines

Comment thread src/mail/ingest.test.ts Outdated
// (`InboundDeliveryStore.preSuppressOwnSend`), reconcile's later `ingest`
// call for that SAME provider id is suppressed instead — never appended.
it("HT-49 review fix: a self-echo of the agent's own sent reply — From the mailbox's OWN address, a foreign (Gmail-rewritten) Message-ID, our token as the FINAL References entry — is suppressed, not appended, once send.ts has pre-seeded its providerMessageId", async () => {
it("HT-49: a self-echo of the agent's own sent reply — From the mailbox's OWN address, a foreign (Gmail-rewritten) Message-ID, our token as the FINAL References entry — is suppressed, not appended, once send.ts has pre-seeded its providerMessageId", async () => {

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

Use Agent for the human support role.

Line 622 describes a human support staff member as agent. Change it to Agent.

As per coding guidelines, call human support staff Agents and AI actors Assistants.

Proposed wording
-  it("HT-49: a self-echo of the agent's own sent reply — From the mailbox's OWN address, a foreign (Gmail-rewritten) Message-ID, our token as the FINAL References entry — is suppressed, not appended, once send.ts has pre-seeded its providerMessageId", async () => {
+  it("HT-49: a self-echo of the Agent's own sent reply — From the mailbox's OWN address, a foreign (Gmail-rewritten) Message-ID, our token as the FINAL References entry — is suppressed, not appended, once send.ts has pre-seeded its providerMessageId", async () => {
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
it("HT-49: a self-echo of the agent's own sent reply — From the mailbox's OWN address, a foreign (Gmail-rewritten) Message-ID, our token as the FINAL References entry — is suppressed, not appended, once send.ts has pre-seeded its providerMessageId", async () => {
it("HT-49: a self-echo of the Agent's own sent reply — From the mailbox's OWN address, a foreign (Gmail-rewritten) Message-ID, our token as the FINAL References entry — is suppressed, not appended, once send.ts has pre-seeded its providerMessageId", async () => {
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/mail/ingest.test.ts` at line 622, Update the test description in the
self-echo scenario to refer to the human support role as “Agent” with the
requested capitalization, while preserving the existing meaning and scenario
details. Use “Agent” for the human support role and reserve “Assistant” for AI
actors.

Source: Coding guidelines

Comment thread src/mail/parse.test.ts Outdated
})

// CodeRabbit follow-up: References may contain CFWS/comments between ids;
// Follow-up: References may contain CFWS/comments between ids;

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

Remove the remaining process labels.

Follow-up still describes review or process history. The PR objective requires forward-facing explanations or removal of process narration. Start each comment with its technical statement instead.

Proposed wording
-  // Follow-up: References may contain CFWS/comments between ids;
+  // References may contain CFWS/comments between ids;

-  // Follow-up (RFC 6854): group-form From must not drop the sender —
+  // RFC 6854: group-form From must not drop the sender —

-  // Follow-up: header names come from untrusted senders. A header
+  // Header names come from untrusted senders. A header

Also applies to: 275-275, 293-293

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

In `@src/mail/parse.test.ts` at line 254, Remove the “Follow-up:” process label
from the comments near the References parsing cases, including the comments at
the identified locations, while preserving the technical explanation about
CFWS/comments between IDs.

zaridan and others added 2 commits August 4, 2026 11:43
Specs narrated how they were made -- "an earlier draft of this section said
it would", "the earlier wording overclaimed" -- and two carried
draft-numbered changelogs naming the tools that reviewed them. A reader has
one version of a document and no interest in what the others said.

Every instance is restated forward. Where a self-correction carried a real
argument, the argument stays: passkeys.md section 8 now asks "why not
log-only across the board?" and answers it. Where it carried none, it is
gone.

The two draft-numbered changelogs become dated entries. agents-and-auth.md
keeps every substantive change from its seven former entries -- mailbox
access, the closed status lifecycle, the acting-Agent header rule, the
advisory-lock serialization, the hardening list -- with PR references
retained. passkeys.md collapses to one entry; none of it has shipped.

Two corrections to the specs themselves, surfaced while rewriting:

- agents-and-auth.md decision point 4 recorded "no scoping behavior or UI"
  while section 3.4 manages real grants with endpoints and a UI. The
  recorded decision is left intact; a supersession note points at 3.4.
- inbound-ingestion.md section 2 had a truncated sentence. Repaired.

Also: spam-classification.md used "the author's judgment" as its INFERRED
marker. A spec has no author-narrator; it now reads "an inference". The
INFERRED and DECIDED markings are unchanged -- who authorized a normative
choice is content.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Source comments named the tooling that prompted a fix -- "CodeRabbit
(Major): claimThreadForDelivery's WHERE clause checked only the lease",
"HT-70 review fix (Codex)", "found by adversarial review" -- and several
recounted what an earlier revision got wrong instead of stating current
behaviour.

Each keeps its technical content and loses the narration. Where a comment
argued against an alternative by describing a past mistake, it now asks the
question directly:

  store/mailboxes.ts    "Why not tell the operator to disconnect and retry?
                         Because that instruction would be false:
                         markDisconnected only sets status ..."
  providers/inbound-email.ts
                        "Why not return a NormalizedInboundEmail? That puts
                         the parse inside the provider ..."
  mail/gmail-reconcile.ts
                        "Why not just ack? The tempting reasoning is 'the
                         holder will advance the cursor' ..."

Ticket and PR references are kept -- "HT-70:", "(PR #94)" -- as navigable
provenance. Vocabulary corrected in three places: "Agent" for a human
support role, "Assistant" for an AI actor, and "module loader" rather than
"plugin loader", since the substrate reserves "plugin" for the legal phrase
"plugin exception".

.coderabbit.yaml is untouched: a tool's own configuration has to name it.

No logic changed. Every edit is inside a comment except eight test titles,
which are descriptive strings.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@zaridan
zaridan force-pushed the chore/public-doc-voice branch from 97f8868 to 6b35be1 Compare August 4, 2026 18:44
@zaridan
zaridan merged commit 7e53a49 into main Aug 4, 2026
8 checks passed
@zaridan
zaridan deleted the chore/public-doc-voice branch August 4, 2026 19:08
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.

1 participant