shipped@di-atomic/customer-comms-reader · v0.1.0 · beta

Absence does not appear in a list.

The state of a client relationship lives in Gmail, Calendar and Drive, and the things that matter most are the ones that are missing: an unanswered thread, a stakeholder who quietly stopped accepting invites, a decision postponed rather than made. customer-comms-reader reads one authenticated account for a named client over a bounded window and returns what was said, decided, promised and left unanswered — with every line traceable to a record you can open.

For anyone running several client relationships out of one inbox, who would rather be told “a meeting ran and I cannot see what was decided” than be handed a confident summary of a week that was never actually read.

A dark chalkboard showing the number 201 struck through in white chalk beside the number 35 circled in gold.
Built by Di-Atomic Marketing & compliance agency Built against a live Google Workspace account, not a fixture 7-language team Clients incl. ONYX Radiance, Pamit Group
201 vs 35what Gmail’s result count claimed, against what was actually there
44 of 44action items Google’s note-taker had already tagged with an owner
3scripts that gate every extract with PASS or FAIL and a number
0replies, sends, files or archives. It reads and nothing else
Installopvs-skills install @di-atomic/customer-comms-reader

Then say: “what happened with Acme this week?” or “what am I sitting on that I haven’t answered?”.

Why a client readout drifts

What scrolling the thread produces
read what is in the inbox
describe what it says
call a week with no email "quiet"

→ the result count said 201; is that real?
→ a meeting ran but nobody wrote it up
→ that quote came from an unsent draft
→ whose reply am I still sitting on?
→ which of the four domains did I search?

(send it Monday, sound certain)

Every one of these produces a confident line that is wrong, and none of them are visible to the reader or to the person who wrote it.

What customer-comms-reader produces
window   explicit instants + IANA timezone,
         read from the account, not assumed
count    full pagination, never the estimate
claim    resolves to a record in harvest.json
         or it is treated as fabricated
absence  a finding with its own source id
rung     which ladder rung supplied it
drafts   dropped at harvest, not cited
scope    domain-scoped is said out loud
footer   counts per surface + what failed

A readout you can check without trusting the writer, because the manifest existed before any of the writing did.

The failure that costs money is not a wrong summary. It is a confident one.

A chalk flow diagram: a white box labelled HARVEST, an arrow to a gold document labelled harvest.json, an arrow to a white box labelled REASON.
Two phases, with a file between them. Harvest reads Gmail, Calendar and Drive and writes the manifest using Google’s own field names. Reasoning runs over that file and reads nothing. Collapse the seam and every claim becomes model-attested, which is another way of saying unverifiable.

Four rungs, and it records which one it stood on

gemini notesGoogle’s note-taker already wrote the decisions and tagged the owners. Parse them rather than re-extract from a transcript.
meeting docAny other notes document in Drive. Decisions and actions are taken; no quotes are attributed to a speaker.
follow-up emailDecisions as reported by a participant afterwards, flagged second-hand rather than presented as the record.
calendar onlyAttendees and responseStatus, and no decision claims at all. This is where it says a meeting ran and what was decided is not visible from here.

Rung one is unavailable on non-English calls — Gemini declines with “not enough conversation in a supported language” — so for a seven-language practice the lower rungs are the normal path, not the exception.

What you actually get

🔗

Every claim resolves, or it does not ship

Harvest writes harvest.json before any reasoning happens, so each claim is checked against a record that provably exists. An id that does not resolve is treated as fabricated, not as a lookup miss.

🕳️

Absence is a finding

“No transcript available” is never rendered as “no decisions were made.” A meeting with no notes is a recorded fact carrying its own source id, because the first phrasing tells you an account is quiet when it may be deciding things without you.

📉

Drift against that person’s own baseline

Escalation is a delta, not a level. A permanently terse engineer is not an alarm; a warm client turning terse is. Six structural signals read responseStatus, timestamps and string length and never body text.

One client, one week, start to finish

> "what happened with VayaPin last week?"

  mechanism ...... gws 0.22.5, authenticated
  window ......... 2026-07-27 → 2026-08-03
                   tz Europe/Kiev, read from the
                   account rather than assumed
  identity ....... 1 domain supplied; the meeting
                   attendees span 4. SAID SO.

  gmail .......... 0 messages in window
  calendar ....... 1 meeting, 5 of 5 accepted
  drive .......... 0 Gemini notes docs found

  ladder ......... degraded to rung 4
                   calendar metadata only
  decisions ...... none claimed, by design

  verify-time-window ............... PASS
  verify-attribution ............... PASS 100%
  lint-pii-exposure ................ PASS

  → "A meeting ran on Jul 28 and all five
     invitees accepted. What was decided is
     not visible from here."

The naive answer to that week is “quiet, nothing to report.” A meeting ran. The difference between those two sentences is the entire product.

Two things it refuses to get wrong

A dark chalkboard showing three identical white chalk squares in a row labelled COUNT, OUTPUT and DRAFT, with the phrase ALL EXIT 0 underlined in gold beneath them.
A failure that returns success is still a failure. A result count that reported 201 for a true 35, an output flag that writes nothing while exiting 0, and an unsent draft whose id is genuine. None of them raise.
A dark chalkboard showing a descending staircase of four chalk rungs labelled NOTES, DOC, EMAIL and CALENDAR, with the lowest rung CALENDAR drawn in gold.
How far down it had to climb is part of the answer. The rung is recorded on every extract, so a decision read off a follow-up email never looks like one read off the minutes.

What it will tell you it cannot do

  • Multilingual is design intent, not a demonstration. The account it was built against runs 99% English, 148 of 150 messages sampled, so six of seven declared languages were never exercised end to end. What was proven: the structural drift signals return byte-identical output with Russian, Hebrew and German bodies substituted.
  • Read-only is enforced by instruction, not by the credential. The token carries gmail.modify. Three files say never send and never file; the credential says nothing. Re-authorising at gmail.readonly would make it structural.
  • Roughly one action item in four is missed. Recall for this task class measures around 77%, which is why every extract closes with counts per surface rather than a claim of completeness.
  • Drive activity history is not reachable. The Activity API is unavailable through this mechanism, so document movement is inferred from modifiedTime and lastModifyingUser instead.
  • It does not own a client roster. The caller supplies the addresses and domains every run. One client routinely spans several domains, so if you pass one, the coverage is reported as domain-scoped rather than client-scoped.
  • Gemini gives up on non-English calls. Exactly the meetings a multilingual practice most needs read are the ones its note-taker declines, which is why the lower rungs exist.
Why this exists

I got tired of reconstructing a client week by scrolling.

customer-comms-reader is one skill in the system behind Di-Atomic — the marketing and compliance agency that runs cognitoAI, SpiderIQ and OPVS. If you want your client relationships read every week in any of our seven languages, including regulated categories, that is the day job.

Book a 30-min call with Di-Atomic

Just want the skill? Get @di-atomic/customer-comms-reader free.