hubspot-deal-pipeline-automation
Automate and audit HubSpot deal pipeline operations without destroying real pipeline — covering stage automation loops, stale-deal safe-close logic, forecast reconciliation, custom property drift detection, quota dashboard cache-busting, and multi-pipeline duplicate detection. Use when writing or debugging workflow automations that move deals between stages, auditing pipelines for stale or duplicated opportunities, reconciling forecast numbers that disagree across reports, or hardening RevOps dashboards against property deletions and reporting-cache lag. Trigger with "hubspot deal pipeline", "hubspot stage automation", "hubspot stale deals", "hubspot forecast reconciliation", "hubspot quota dashboard", "hubspot duplicate deals", "revops pipeline audit".
What this skill does
# HubSpot Deal Pipeline Automation
## Overview
Automate HubSpot deal pipelines without blowing up real revenue. This is not a
walkthrough of workflow builder UI — it is the engineering behind six failure
modes that silently destroy RevOps data while every dashboard stays green until
a rep's quota call reveals the damage.
The six production failures this skill prevents:
1. **Stage automation loops** — a workflow moves a deal to "Demo Scheduled",
which triggers a second workflow enrolled on "Demo Scheduled" that moves it
back to "Qualified", which triggers the first workflow again. The deal
bounces between stages until HubSpot's 100-action daily workflow execution
limit for that deal is exhausted. RevOps sees "workflow failure" alerts but
no stage history that makes sense.
2. **Stale-deal auto-closing** — a cleanup workflow auto-closes deals older
than 90 days to clear pipeline bloat. The contact associated with deal #4872
responded to an email this morning. The deal is closed as Lost. The rep calls
the contact, who says "I just told someone we were ready to sign." This
failure costs quota attainment, not just data quality.
3. **Forecast query inconsistency** — `amount`, `hs_projected_amount`, and a
custom `arr_value` property all exist on the same deal. The CRO dashboard
queries `amount`. The ops team queries `hs_projected_amount`. RevOps built a
custom rollup on `arr_value`. At end of quarter they produce three different
forecast numbers for the same deal set with no canonical answer.
4. **Custom property reporting gap** — a RevOps engineer renames
`deal_source_detail` to `original_lead_source` in the property settings.
Every deal-source dashboard built on the old property name silently returns
zero. No error is thrown. The board sees a 100% collapse in deal source
tracking that is entirely an artifact, not a pipeline signal.
5. **Quota dashboard staleness** — HubSpot's reporting layer caches deal stage
aggregates. A deal closes at 4:47pm. The quota attainment dashboard doesn't
reflect it until 8:30pm. A rep who hit quota at EOD is told they're 3%
short. This is a 4-hour cache lag in the default reporting stack, and it
affects every quota conversation at month-end.
6. **Multi-pipeline deal duplication** — a new business opportunity becomes an
expansion after the initial close. Someone creates a deal in the Expansion
pipeline for the same company without deleting the original, or a workflow
auto-creates expansion deals. The same revenue is counted in two pipeline
forecasts with no cross-reference key linking them.
## Prerequisites
All API calls use a HubSpot private app token or OAuth access token in the
`Authorization: Bearer $HUBSPOT_TOKEN` header. The `hubspot-auth` skill covers
token caching, rotation, and rate-limit backoff patterns. For deal pipeline
automation, the required scopes are listed below.
- HubSpot Sales Hub Professional or Enterprise (workflows + custom properties
- API access)
- Private app token with scopes:
`crm.objects.deals.read`, `crm.objects.deals.write`,
`crm.schemas.deals.read`, `crm.schemas.deals.write`,
`crm.associations.read`, `crm.associations.write`,
`automation`
- Node.js 18+ or Python 3.10+ in the execution environment
- `jq` installed for shell-based audit scripts
- HubSpot portal ID (visible at top-right of any HubSpot page, or via
`GET /oauth/v1/access-tokens/$TOKEN`)
## Instructions
Build in this order. Each section neutralizes one production failure mode.
### 1. Stage transition guard (neutralizes automation loops)
Workflow loops happen when a stage-change trigger has no memory of what caused
the change. The guard injects a sentinel property `hs_pipeline_loop_guard`
(type: `string`, format: `workflowId:epochMs`) that any workflow writes
immediately before it changes a stage, and reads before it fires. If the guard
was written by the same workflow within a debounce window, the workflow aborts.
**Create the sentinel property first (one-time setup per portal):**
```bash
curl -s -X POST "https://api.hubapi.com/crm/v3/properties/deals" \
-H "Authorization: Bearer $HUBSPOT_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"name": "hs_pipeline_loop_guard",
"label": "Pipeline Loop Guard",
"type": "string",
"fieldType": "text",
"groupName": "dealinformation",
"description": "Automation loop sentinel. Format: workflowId:epochMs. Written before any stage transition."
}' | jq '{name, label, type}'
```
**TypeScript guard — wrap every stage-change call in this:**
```typescript
const DEBOUNCE_MS = 60_000; // 60s window per workflow
async function safeStageTransition(
dealId: string,
workflowId: string,
targetStageId: string,
token: string,
): Promise<{ transitioned: boolean; reason: string }> {
// Read current guard value
const deal = await hubspotGet(`/crm/v3/objects/deals/${dealId}`, token, {
properties: "dealstage,hs_pipeline_loop_guard",
});
const guard: string | null = deal.properties.hs_pipeline_loop_guard ?? null;
if (guard) {
const [guardedWorkflowId, tsStr] = guard.split(":");
const elapsed = Date.now() - parseInt(tsStr, 10);
if (guardedWorkflowId === workflowId && elapsed < DEBOUNCE_MS) {
return {
transitioned: false,
reason: `Loop guard: workflow ${workflowId} already fired ${elapsed}ms ago`,
};
}
}
// Write guard, then transition
await hubspotPatch(`/crm/v3/objects/deals/${dealId}`, token, {
properties: {
hs_pipeline_loop_guard: `${workflowId}:${Date.now()}`,
dealstage: targetStageId,
},
});
return { transitioned: true, reason: "OK" };
}
```
`hubspotGet` and `hubspotPatch` are thin `fetch` wrappers — implementations in
[implementation-guide.md](references/implementation-guide.md).
**Detecting existing loops via stage history audit:**
```bash
# Pull stage change history for a specific deal — look for oscillation
DEAL_ID="12345678"
curl -s "https://api.hubapi.com/crm/v3/objects/deals/${DEAL_ID}/changelog" \
-H "Authorization: Bearer $HUBSPOT_TOKEN" | \
jq '.results[] | select(.propertyName == "dealstage") | {timestamp, from: .previousValue, to: .currentValue}'
```
If the output shows the same two stage IDs alternating more than twice in 24
hours, that deal has a live loop. Identify the responsible workflows by checking
`hs_lastmodifieddate` on the deal alongside the workflow enrollment history in
HubSpot UI (Contacts → Workflows → History tab for the deal).
### 2. Stale-deal safe-close audit (neutralizes stale-deal closing)
Never auto-close a deal without first checking whether the associated contact
has recent email activity. The safe-close criterion is: deal older than 90 days
**AND** no inbound email in the last 30 days **AND** no open tasks.
The full `stale_deal_audit.py` script (with `get_stale_open_deals`, `has_recent_inbound_email`, `has_open_tasks`, and paginated search) lives in [implementation-guide.md](references/implementation-guide.md) § Stale-Deal Audit.
Key points for the search query:
```bash
# CRM search filter for stale open deals (epoch ms cutoff)
CUTOFF=$(python3 -c "import datetime; print(int((datetime.datetime.utcnow()-datetime.timedelta(days=90)).timestamp()*1000))")
# filterGroups: createdate LT $CUTOFF AND hs_is_closed EQ false
```
The script outputs a CSV with `safe_to_close` boolean. Only rows where `safe_to_close=True` are candidates for batch close. A separate `batch_close_stale.py` script (also in the implementation guide) handles the actual close — always requires human review of the CSV before executing.
### 3. Forecast amount reconciliation (neutralizes query inconsistency)
HubSpot exposes four distinct amount-like fields on a deal. Using the wrong one
in a report produces a different number without any error. The canonical
selection logic:
| Field | When it is the right number |
|---|---|
| `amount` | The rep-entered deal valuRelated in Security
mac-ops
IncludedComprehensive macOS workstation operations — diagnose kernel panics, identify failing drives, audit launchd startup items, decode wake reasons, triage TCC permission denials, manage APFS snapshots, recover from no-boot. Use for: Mac is slow, slow bootup, won't boot, kernel panic, kernel_task hot, mds_stores CPU, photoanalysisd, cloudd, login loop, gray screen, sleep wake failure, drive failing, IO errors, APFS snapshots eating space, Time Machine local snapshots, Spotlight indexing, launchd, LaunchAgent, LaunchDaemon, login items, TCC permissions, Full Disk Access, Screen Recording denied, Gatekeeper, quarantine, com.apple.quarantine, app is damaged, helper tool, /Library/PrivilegedHelperTools, pmset, wake reasons, dark wake, sysdiagnose, panic.ips, DiagnosticReports, configuration profile, MDM profile, remote diagnostics over SSH.
a11y-audit
IncludedRun accessibility audits on web projects combining automated scanning (axe-core, Lighthouse) with WCAG 2.1 AA compliance mapping, manual check guidance, and structured reporting. Output is configurable: markdown report only, markdown plus machine-readable JSON, or markdown plus issue tracker integration. Use this skill whenever the user mentions "accessibility audit", "a11y audit", "WCAG audit", "accessibility check", "compliance scan", or asks to check a web project for accessibility issues. Also trigger when the user wants to verify WCAG conformance or map findings to a specific standard (CAN-ASC-6.2, EN 301 549, ADA/AODA).
erpclaw
IncludedAI-native ERP system with self-extending OS. Full accounting, invoicing, inventory, purchasing, tax, billing, HR, payroll, advanced accounting (ASC 606/842, intercompany, consolidation), and financial reporting. 413 actions across 14 domains, 43 expansion modules. Constitutional guardrails, adversarial audit, schema migration. Double-entry GL, immutable audit trail, US GAAP.
assess
IncludedAssesses and rates quality 0-10 across multiple dimensions (correctness, maintainability, security, performance, testability, simplicity) with pros/cons analysis. Compares against project conventions and prior decisions from memory. Produces structured evaluation reports with actionable improvement suggestions. Use when evaluating code, designs, architectures, or comparing alternative approaches.
spring-boot-security-jwt
IncludedProvides JWT authentication and authorization patterns for Spring Boot 3.5.x covering token generation with JJWT, Bearer/cookie authentication, database/OAuth2 integration, and RBAC/permission-based access control using Spring Security 6.x. Use when implementing authentication or authorization in Spring Boot applications.
code-hardcode-audit
IncludedDetect hardcoded values, magic numbers, and leaked secrets. TRIGGERS - hardcode audit, magic numbers, PLR2004, secret scanning.