Inspiration

I have spent more than a decade in marketing, much of it inside B2B SaaS companies working across performance campaigns, ABM, CRM operations, reporting, and global demand generation.

One question followed through all of those roles: How much pipeline did marketing actually create?

A dashboard can answer in seconds. I learned to inspect the evidence underneath it first.

A precise pipeline number can rest on missing source fields, contacts with no company, deals with no contact, lifecycle stages overwritten by automation, or a sales handoff that exists in a process document and nowhere in the CRM. When the evidence is weak, a polished report only makes the uncertainty look more convincing.

I first encountered the wider problem through campaign work. Poor performance often led back to the ICP, messaging, content, or sales follow-up. Measuring the channel gave me a clean view of the symptom and an incomplete view of the system.

That experience shaped B2B Growth Audit. Before a CMO decides which channel to scale or which workflow to rebuild, two questions need separate answers:

  1. Is their CRM data reliable enough to support the decision?
  2. Is their business turning demand into pipeline without preventable breaks?

Those questions became two independent, open-source agent skills I built with GPT 5.6.

CRM Trust Audit examines attribution, lifecycle data, company, contact, and deal associations, pipeline hygiene, property governance, and record traceability. It establishes what the business can safely trust.

Lifecycle Integrity Audit discovers the selling journeys represented in HubSpot, then traces those journeys to find broken handoffs, ignored intent, exposed open deals, and credible recovery opportunities.

How I built it

I built the project with Codex as a coding and review partner. I defined the commercial questions, evidence standards, dangerous assumptions, and decisions a CMO would need to make. Codex helped turn that judgment into Python, tests, agent contracts, and reports.

The package supports Codex, Claude Code, and Gemini CLI, with agent-agnostic contracts that other capable coding agents can follow. It uses the host agent for judgment, so the repository requires no separate model API key. A live audit still requires a HubSpot Private App token.

The architecture follows one rule: code measures, bounded agents interpret, and humans decide.

Each audit connects to HubSpot through an explicit read-only endpoint allowlist. The connector handles pagination, rate limits, checkpoints, and resume. Customer snapshots stay local. The code contains no path for creating, updating, merging, deleting, reassigning, or stage-changing CRM records.

Python owns the facts it can verify: data acquisition, normalization, counts, percentages, score arithmetic, validation, and report rendering. It produces sanitized evidence stores with per-run hashed record identifiers.

The agent harness packages each analysis or review task with only its declared inputs and a structured output contract. The role never sees the raw snapshot. Independent reviewers challenge ambiguous findings. A final gate checks privacy, evidence links, and score consistency before the report can pass.

Each audit produces its own Markdown and HTML report, evidence set, score or explicit unassessable result, and operator appendix. The headline audit scores stay separate, while Lifecycle also reports Journey Mapping Confidence as a distinct measure. Strong lifecycle execution cannot make unreliable attribution evidence trustworthy. Clean data also provides no proof that a sales handoff happened.

Challenges and iterations

Refusing the master score

One impressive B2B Growth Score would have been easier to explain in a demo. It would also have hidden the product's most important dependency.

The lifecycle analysis relies on CRM evidence. A weak CRM Trust result must limit confidence in the affected lifecycle conclusions. I therefore kept the audits independent, gave each one its own evidence and scoring contract, and prohibited averaging the results.

The result is less tidy and more defensible. A CMO can see whether the problem is unreliable evidence, broken execution, or both.

Learning when a number should disappear

HubSpot permissions and product tiers created a harder problem. Workflow access uses the broad automation scope. Campaign data may be unavailable on some plans. A successful activity endpoint with no records means something very different from an endpoint the audit could not access.

Earlier scoring logic could make incomplete coverage look healthier than it was. I changed the system to distinguish unavailable, partial, and observed-with-no-events sources. Missing data no longer becomes zero activity. Unassessable controls reduce scored coverage instead of earning healthy points or becoming failures. In the current build, the audit withholds the numeric Lifecycle Integrity Score below 70 percent weighted coverage.

That became the central product lesson: a trustworthy audit needs permission to say, "There is not enough evidence to score this responsibly."

Making evidence useful without exposing or changing customer data

The first report design carried too much technical detail in the main narrative. The logic was traceable, but a CMO still had to search for the decision.

I reorganized the reports around the human review path. CRM Trust now shows which management decisions each data problem may distort and where the reporting boundary sits. Lifecycle Integrity opens with the detected journeys, then shows the leakage, existing deal exposure, recovery populations, supporting evidence, and the next human action. Full profiling and implementation detail moved into the operator appendix.

The privacy boundary had to survive that push toward record-level evidence. Raw snapshots, contact identity, message bodies, and tokens stay outside agent tasks. Processed artifacts use aggregates, redacted values, and salted hashes. The confidential local report may include only the minimum account, contact, deal, and owner labels an authorized reviewer needs to act.

Some HubSpot scopes expose more capability at the platform level than the audit uses. I treated documentation as insufficient protection. The client rejects every route outside its read allowlist, final gates flag dangerous recommendation language, and every finding carries auto_fix_allowed: false. Recommendation plans name the required human approval and success condition. The report can guide a human review. It cannot change the CRM.

Real customer exports could never become public test fixtures. I built synthetic portals covering clean data, broken attribution, association failures, property sprawl, inbound, outbound, ABM, partner, expansion, mixed-motion, and pipeline leakage. Golden tests encode the expected journeys and findings. CI scans the fixtures for non-reserved email domains and HubSpot-looking tokens.

What I learned

Building this changed how I divide work with AI. Models handle interpretation, ambiguity, and explanation. Deterministic code owns measurements, score arithmetic, validation, and failure states.

I also learned that unassessable is a valid result. Most dashboards are designed to complete the chart. An audit earns trust by showing where the evidence ends.

My marketing experience became part of the product architecture. Years of working with HubSpot, ABM, demand generation, attribution, and sales handoffs shaped the measurements. The recurring gap between a campaign symptom and a system problem shaped the two-audit sequence.

B2B Growth Audit gives a CMO a defensible path: establish what can be trusted, find where the revenue journey breaks, inspect the record-level evidence, and decide what to repair next.

When the evidence cannot support that decision, the audit says so and stops short of a numeric score. That may be the most valuable answer it produces.

Built With

Share this project:

Updates