Claude CoWork Activation Plane
01

Overview

Real_Estate_Auto_Enrichment_Claude_CoWork

The Claude CoWork branch runs the same enrichment framework as the GCP branch — the same parsers, schema, indications, round trips and adversarial-monitor lane — but puts a person and a set of custom skills in front of it. CoWork starts and steers enrichment runs from chat, and then works the enriched leads through the HubSpot connector: outreach, scheduling, activity logging, deal conversion and content.

The activation plane

Two things make up the activation plane for a deployment:

  1. The custom skills — packaged, repeatable workflows that know the probate program's rules: the brand, the compliance guardrails, the approval gates and the field-governance model.
  2. The CoWork–HubSpot connection — the Cowork HubSpot connector, which reads the whole enriched record and writes activity back onto native HubSpot objects, alongside Gmail, Google Calendar and Google Drive.

The framework fills the record. The activation plane turns the record into a conversation, a meeting, a deal or a published post, and logs every action back onto the same contact.

Lead-in product: CoWork integration is the entry point for future deployments. A new client starts with the HubSpot connector and the skills on day one, runs enrichment on demand from CoWork, and moves to the scheduled Cloud Run jobs only when volume calls for it. See the User & Deployment Guide tab.

Two patterns, one portal

PatternWho actsWhat it ownsHow it writes
A — Enrichment framework Scripts, started from CoWork chat (this branch) or Cloud Run jobs (GCP branch) Every retrieval/enrichment custom field: listing, valuation, auditor, recorder, probate docket, indication_* flags, enrichment_stage, stage_*, archive fields HubSpot Batch API, keyed on lead_uid
B — User-level engagement A person in CoWork, through the custom skills Native HubSpot objects: tasks, notes, calls, meetings, emails, lead status (working funnel), deals, blog posts Cowork HubSpot connector, every write through field_guard.py

Data flow

RapidUpload - File Drop v-1.1 ──▶ HubSpot contact (PENDING, lead_uid)
                                        │
   CoWork chat ── run_enrichment.py ────┤  Pattern A: S0 · A1 · A2 · B · C · LOAD
                                        │  DNC + contact append round trips
                                        ▼
                          enriched, routable HubSpot record
                                        │  read (unrestricted)
                                        ▼
   CoWork + custom skills ──────────────┤  Pattern B: outreach · appointment · log
     (HubSpot connector, Gmail,         │  status · deal · blog · social
      Calendar, Drive)                  ▼
                          activity logged back on native objects

CoWork vs GCP Cloud Run

FunctionClaude CoWork (this branch)GCP Cloud Run ADK
Execution modelOn-demand, chat-enabled — or scheduledNo-touch, scheduled batch processing
How a run startsA chat command in a CoWork sessionA scheduled job — daily or every 15 / 5 / 1 minute
Human interactionHuman-in-the-loop; inspect and adjust mid-flightUnattended once deployed
After enrichmentSame session works the leads through the custom skillsHands off to CoWork for engagement
Best forNew deployments, ad-hoc runs, catch-up, county targeting, debugging, trial passesSteady-state daily / weekly enrichment at scale

The CoWork–HubSpot connection

The Cowork HubSpot connector is the other half of the activation plane. Both patterns share one portal, so the connection is governed by a single rule:

Read anything. Never write the framework's tokenized custom fields. Those fields follow the framework's write convention and return a HubSpot 400 if written any other way.

Connector tools

DirectionToolsNotes
Readget_crm_objects, search_crm_objects, query_crm_dataReturn custom properties by internal name, including the whole enrichment channel
WriteObject update, engagement and association toolsOnly the allowed set from field_guard.py is ever sent
ContentBlog post create / update / publishUsed by the content studio for draft upsert and go-live

The field guard

scripts/field_guard.py reads assets/field_governance.json (denylist model, version 2) and checks every proposed property in order:

  1. hs_lead_status — dropped if the target is ARCHIVE_LISTED, ARCHIVE_SOLD, ARCHIVE_VALUE or ARCHIVE_DNC. Archiving is the framework's decision. Any working-funnel value is allowed.
  2. Immutable keys — lead_uid, lead_id, createdate, ingest_timestamp, hs_object_id are never overwritten.
  3. Protected framework fields — dropped if the name is on the protected list or matches a configured prefix or pattern.
  4. Everything else is allowed — native objects and standard properties.

After any workflow the skill reports what it read, what it sent or updated, and anything the guard dropped, so the line between the person's actions and the framework's fields stays visible.

Protected vs writable

Protected (framework-owned)Writable (native / standard)
Valuation and listing: property_value, property_estimated_value, property_listing_urlEngagements: tasks, notes, calls, meetings, emails
Auditor, parcel, tax, legal, recorder, liens, TOD filingsTask fields: hs_task_subject, hs_task_status, hs_task_type, hs_timestamp
Probate: probate_court_url, probate_case_number, parties, costs, dockeths_lead_status working funnel (not ARCHIVE_*)
indication_* flagshubspot_owner_id
enrichment_stage, stage_*_complete, stage_*_engaged, archive_*, minimum_property_valueDeal fields: dealname, dealstage, pipeline, amount, closedate

Keep the denylist current against the live schema. If the framework's fields share a naming convention, set protected_prefixes or protected_name_patterns so new fields are protected automatically — without matching native hs_* names.

Lead → deal, without duplicates

Setting hs_lead_status = Open Deal is the trigger. On the full system the framework's open-deal mode also mirrors the contact onto a deal, so the skill creates deals idempotently: it checks for a deal already associated with the contact in the target pipeline and updates it, or creates one if none exists. The native contact↔deal association is the key; no custom snapshot fields are added, and the enrichment data stays reachable through the association.

Where the connection meets the framework

ContractFramework (Pattern A)CoWork skills (Pattern B)
IdentityMints and adopts lead_uidReads it; never writes it
Lead statusWrites indication-derived status and all ARCHIVE_* outcomesMoves the working funnel and sets Open Deal
ContactabilityWrites contactable_channel and DNC stateHonors them on every send
Activity—Logs every touch on native engagement objects
↑ Back to top
02

CoWork Admin Capability

scripts/run_enrichment.py

On this branch the orchestrator is scripts/run_enrichment.py, driven from a CoWork session. This is the admin skill of the activation layer: API batch processing across the portal, started and watched from chat. Full stage, schedule and schema detail lives in the Real Estate Enrichment Automation Framework reference.

What a run does

StageSourceWrites
S0HubSpotReconcile: adopt lead_uid, drop duplicates, snapshot
A1Listing sites via Firecrawl /search (Zillow → Realtor.com → Redfin)Listing status, estimated value, cached listing URL; archives below the value floor
A2County auditor (ArcGIS parcel layer)Parcel, legal description, assessed value, tax, delinquency, last transfer date
BCounty recorder via Firecrawl /interactLiens and transfer-on-death filings (weekly default off)
CProbate docket via /interact + /extractParties, letters, will, hearings, indication flags and lead status
LOADHubSpot onlyRe-scores indication flags and lead status without Firecrawl
D / EContact append and DNC round trips through File Dropcontactable_channel, dnc_status_detail, validated phone and email
Scripted extraction only. The Firecrawl Agent API is turned off by design. Every stage calls the scripted endpoints directly, which keeps extraction deterministic and removes hallucinated values.

Driving it from chat

CoWork runs the CLI with the same flags the Cloud Run jobs wrap: --mode, --stages, --county, --limit, --oldest, --dry-run / --apply.

python3 scripts/run_enrichment.py --mode weekly --dry-run
python3 scripts/run_enrichment.py --mode catchup --stages A1 --limit 10 --oldest --dry-run
python3 scripts/run_enrichment.py --mode catchup --stages C --county Medina --limit 10 --oldest --apply
python3 scripts/run_enrichment.py --mode update --apply
python3 scripts/run_enrichment.py --mode catchup --stages LOAD --apply

Operating modes

ModeSelectsTypical CoWork use
weeklyNew leads pending enrichment (A1 then C)Process a fresh File Drop batch the same day it lands
updateCompleted non-archive leads (A1 listing + C docket)Refresh listing status and dockets before an outreach push
catchupRecords where the named stage is not completeTrial passes with --limit 10, one county at a time
open-dealhs_lead_status = Open Deal (A2 + Contact → Deal)Enrich a lead the moment it converts
--stages LOADLive contacts, no FirecrawlRe-score flags after a CRM-logic change

Stage Engagement card

The Stage Engagement card on the control contact lead_uid=PIPELINE_SETTINGS sets the A1 value floor (default 175,000) and switches Stage B (default off) and Stage C (default on) for scheduled runs. Catch-up runs ignore the B/C toggles and always run the named stage.

↑ Back to top
03

CoWork User

User-level engagement layer · Pattern B

Skills are the part of the activation plane a person actually uses. Each one packages a workflow with its rules, so the same request produces the same compliant, on-brand result every time. Custom skills were built for this program; plugin skills come from installed packages and fill in general CRM and social tasks.

Skill catalog

SkillTypeWhat it doesConnectors
probate-lead-engagement-googleCustomWorks an existing lead: personalized email, status, appointments, activity logging, lead → deal. Guards every HubSpot write.HubSpot, Gmail, Google Calendar
probate-content-studio-googleCustomResearches topics, drafts blog and social content, publishes to the HubSpot blog after approval.HubSpot blog, Google Drive, web search
plum-tree-probate-brandCustomClient brand chrome for every outbound probate email (Plum Tree / BuySellLiveOhio).Gmail, HubSpot inline email module
hubspot-salesPluginCRM query and enablement: contact lookup, pipeline pulse, daily brief, call prep, log call, follow-up, import, onboarding.HubSpot
postizPluginSocial scheduling, media upload and analytics across 28+ channels.Postiz CLI / MCP

Capability map

CapabilitySkills
Admin — API batch processrun_enrichment.py from CoWork chat (see CoWork Admin Capability)
Brandingplum-tree-probate-brand
Personalized outreach creationprobate-lead-engagement-google + plum-tree-probate-brand
CRM loggingprobate-lead-engagement-google · hubspot-sales log-call
CRM queryhubspot-sales (contact lookup, pipeline pulse, daily brief, call prep)
CRM enablementhubspot-sales (onboarding, import contacts) · lead → deal conversion
Blog postprobate-content-studio-google
Social media retrievalpostiz (analytics, post lists)
Post generationprobate-content-studio-google (drafts) → postiz (scheduling)

probate-lead-engagement-google

The human-in-the-loop engagement layer over the probate portal. It reads the full record, including every enrichment field, and writes only to native HubSpot objects. New-lead creation is not enabled at this level, so the framework stays the only minter of lead_uid.

Every workflow follows one spine: read the portal → act through Google Workspace → log back onto existing native objects.

WorkflowStepsLogged as
1 — Personalized outreachRead record → screen out archived, DNC or recently contacted → draft and brand → resolve merge tokens from portal data → approve → send through GmailCompleted email engagement with the send date and time; prompting task marked complete
2 — Status updateMove through NEW → Contacted → Working → Nurture → Open Deal → UnqualifiedNative note with the reason. ARCHIVE_* is blocked.
3 — Schedule an appointmentConfirm slot → Google Calendar event, contact invited, lead context in the bodyNative meeting engagement
4 — Log activityCall, note, task or communication on the matching engagement typeExisting task updated in place (hs_task_status); new task only when none exists
5 — Convert lead → dealSet Open Deal → find-or-create one deal per contact → associate → standard deal fieldsNative note or meeting on both contact and deal
Email never goes through the portal. Templates are authored with HubSpot merge tokens, but HubSpot only renders those when it sends. Because outreach sends from the user's own Google Workspace account, the skill resolves every token from the record first. Open and click tracking can still layer on through the HubSpot Sales Gmail integration.

probate-content-studio-google

A recurring content engine for Plum Tree Real Estate Marketing / BuySellLiveOhio.com. Three stages, each separated by a human approval gate, with every item tracked in a JSON ledger (content_state.py) so nothing is lost between scheduled runs.

  1. Research — a scheduled CoWork task (default weekly, Monday 08:00 ET) scans probate, estate, inherited-property and Northeast Ohio market topics, scores them, writes a research brief per idea and sends a digest of the best 2–3. Gate 1: the user picks.
  2. Draft — writes the blog post and upserts it into HubSpot as a draft, writes one social variant per channel (LinkedIn, Facebook, optional Instagram and X), then self-checks compliance. Gate 2: the user edits and approves.
  3. Publish / schedule — publishes or schedules the approved draft on HubSpot's hosted blog and records the live URL; schedules social where a connector exists, otherwise hands over a ready-to-post package. Gate 3: go-live time confirmed.

Ledger statuses: RESEARCHED → PICKED → DRAFTED → APPROVED → SCHEDULED → PUBLISHED, with HOLD and REJECTED for ideas set aside.

Brand skill

SkillBrandApplies toIdentity
plum-tree-probate-brandClient — Plum Tree Real Estate Marketing / BuySellLiveOhio.comFamily-representative intro, attorney intro, attorney thank-you / follow-up, nurture emails; blog and social visuals reuse its tokensPlum #3a1a55 + gold #c9a84c; Georgia serif letter voice, Arial structure; one invariant chrome, only the body and tagline change

Anything a probate family or attorney receives carries the client brand, with identical chrome on every send.

Plugin skills

  • hubspot-sales (by HubSpot) — the entry point for general CRM questions and quick updates: contact lookup, pipeline pulse, daily brief, call prep, call logging, follow-up drafts, contact import and portal onboarding.
  • postiz — social scheduling, media upload and analytics across 28+ platforms. Media must go through postiz upload before it can be attached to a post.

Guardrails shared by every skill

  • Human-in-the-loop. Outreach, publishing and posting are drafted, shown and sent only on explicit approval.
  • No legal advice. The program is not a law firm; content explains process generally and points to an attorney where a topic touches legal steps.
  • Empathy first. No pressure tactics or "motivated seller" language; the audience is often grieving.
  • Fair housing and honesty. No steering, no fake urgency, no guaranteed outcomes.
  • Never contact archived or DNC records. Outreach keys on contactable_channel.
↑ Back to top
04

User & Deployment Guide

CoWork as the lead-in product

CoWork integration is the lead-in product for future deployments. A client gets value from the activation plane before any cloud infrastructure exists: the skills and the HubSpot connection work against any portal, and the framework runs on demand from the same CoWork session.

Deployment sequence

  1. Connect the portal. Attach the Cowork HubSpot connector and the client's Google Workspace (Gmail, Calendar, Drive).
  2. Install the skills. Engagement, content studio, the client brand skill, and the hubspot-sales and postiz plugins.
  3. Configure field governance. Verify field_governance.json against the live schema before the first write.
  4. Load and enrich on demand. Run RapidUpload - File Drop v-1.1 for ingest, then run_enrichment.py from CoWork chat — trial passes first (--limit 10 --dry-run), one stage and county at a time.
  5. Work the leads. Outreach, appointments, activity logging and deal conversion through the engagement skill; content through the content studio.
  6. Schedule the recurring work. The weekly content research task and any recurring enrichment runs as CoWork scheduled tasks.
  7. Graduate to Cloud Run when volume calls for it. The GCP branch runs the identical framework unattended; CoWork stays the engagement layer on top.

What carries over to a new client

ComponentReused as-isPer client
Engagement skillWorkflows, field guard, deal conversionDenylist verified against that portal's schema
Content studioThree-gate pipeline, ledger, compliance checklistEditorial guidelines, channels, Drive folders, schedule
Brand skillComponent structure and token modelThe client's palette, logo, signature and credentials
Workspace stackGoogle Workspace variants shippedA parallel Microsoft 365 / Outlook / SharePoint variant exists for M365 clients
FrameworkParsers, schema, indications, round tripsCounty registry and portal properties (create_hubspot_properties.py)

Status

LayerScopeStatus
RapidUpload - File Drop v-1.1Drive → master ledger → HubSpot ingestComplete
Enrichment frameworkS0 · A1 · A2 · B · C · LOAD · D · E, on CoWork and Cloud RunComplete
CoWork activation planeCustom skills + CoWork–HubSpot connectionComplete
Future deploymentsCoWork-led rollout to new clientsPlanned
↑ Back to top