{"@id":"https://artemisgtm.ai/resources/gtm-systems-teardown-rubric/#ownership","id":"ownership","number":1,"name":"Ownership","question":"Does every inbound lead, account and alert have exactly one named owner of record, set by a rule at the moment the record is created?","failureSmell":"Leads sit with an empty owner or with an integration user as owner, reps ask in Slack who has an account, and two reps work the same buyer while another lead waits with nobody.","measurement":"Count records created in the window where owner_id is null or points at an inactive or integration user, and count accounts whose open contacts carry more than one distinct owner_id. For any record older than the assignment step, both counts should be zero.","fix":"Resolve the owner in one place and in a fixed order: existing account owner, then the territory table, then a round-robin pool that respects availability, then a named fallback owner. Write owner_id and owner_assigned_at in the same step that creates the record, and alert on any record that leaves that step without both.","patterns":["https://artemisgtm.ai/resources/gtm-systems-patterns/#owner-of-record-routing"],"scenarios":["https://artemisgtm.ai/resources/pipeline-debugging-scenarios/#the-unanswered-demo-request","https://artemisgtm.ai/resources/pipeline-debugging-scenarios/#the-dropped-handoff","https://artemisgtm.ai/resources/pipeline-debugging-scenarios/#the-alert-nobody-owns"],"sources":[],"contributor":null,"publisher":"Artemis GTM","author":"Tom Regan","license":"https://creativecommons.org/licenses/by/4.0/","version":"2026.10","since":"2026.10","lastReviewed":"2026-10-18"}
{"@id":"https://artemisgtm.ai/resources/gtm-systems-teardown-rubric/#latency","id":"latency","number":2,"name":"Latency","question":"Does a hand-raise (a demo request, a contact-sales form, a reply) reach a human who acts on it inside the sub-5-minute standard, around the clock, with an escalation when nobody does?","failureSmell":"Response time is a feeling rather than a number, the median only looks healthy because off-hours leads are left out of it, and a form filled on Friday evening gets its first touch on Monday.","measurement":"Stamp lead_created_at and first_touch_at on every inbound record and compute response_minutes = first_touch_at - lead_created_at. Report the median and the slowest decile across all 168 hours of the week, split by source and by in-hours versus off-hours, and count records where first_touch_at is still null.","fix":"Start a timer at lead_created_at that escalates while claimed_at is empty: to the pool at the first threshold, to a manager at the second. Send an automated first touch to after-hours leads so the buyer hears back in minutes, and log it apart from the human first touch so it never flatters the number.","patterns":["https://artemisgtm.ai/resources/gtm-systems-patterns/#sla-timer-with-escalation","https://artemisgtm.ai/resources/gtm-systems-patterns/#four-timestamp-write-back","https://artemisgtm.ai/resources/gtm-systems-patterns/#capacity-bound-threshold-bands"],"scenarios":["https://artemisgtm.ai/resources/pipeline-debugging-scenarios/#the-unanswered-demo-request","https://artemisgtm.ai/resources/pipeline-debugging-scenarios/#the-alert-nobody-owns"],"sources":[{"label":"Harvard Business Review (March 2011, Oldroyd, McElheran, Elkington), \"The Short Life of Online Sales Leads\"","note":"put the average first response to a web lead near 42 hours, in a review of how companies answered inbound web leads.","url":"https://hbr.org/2011/03/the-short-life-of-online-sales-leads"},{"label":"Lead Response Management study (Oldroyd, 2007)","note":"found leads worked within 5 minutes roughly 21x likelier to qualify than leads worked at 30 minutes (directional). Named, not linked: the study has no live canonical home.","url":null}],"contributor":null,"publisher":"Artemis GTM","author":"Tom Regan","license":"https://creativecommons.org/licenses/by/4.0/","version":"2026.10","since":"2026.10","lastReviewed":"2026-10-18"}
{"@id":"https://artemisgtm.ai/resources/gtm-systems-teardown-rubric/#idempotency-and-dedup","id":"idempotency-and-dedup","number":3,"name":"Idempotency and dedup","question":"When the same event arrives twice (a resubmitted form, a retried webhook, a visitor back in a new session), does the system still create one record, one sequence enrollment and one alert?","failureSmell":"Contacts that differ only by letter case or a trailing space in the email, a buyer enrolled in two sequences by two workflows, and an alert channel where the same visitor appears several times a week.","measurement":"Group contacts by normalized_email (lowercased and trimmed) and accounts by normalized_domain, and count groups holding more than one record. For events, log an event_id or a hash of source, payload key and time bucket, and count keys processed more than once. For alerts, count alerts per contact_id inside one dedup window.","fix":"Give every inbound event an idempotency key and refuse a second write with a key already seen; upsert on normalized_email instead of inserting. Thread repeat signals for one contact under the original alert for the length of a dedup window instead of posting a new one.","patterns":["https://artemisgtm.ai/resources/gtm-systems-patterns/#idempotent-event-ingestion","https://artemisgtm.ai/resources/gtm-systems-patterns/#alert-dedup-window"],"scenarios":["https://artemisgtm.ai/resources/pipeline-debugging-scenarios/#the-forked-record","https://artemisgtm.ai/resources/pipeline-debugging-scenarios/#the-alert-nobody-owns"],"sources":[{"label":"Stripe API reference, \"Idempotent requests\"","note":"documents the idempotency-key mechanism, where a retried request with the same key returns the first result instead of acting twice.","url":"https://docs.stripe.com/api/idempotent_requests"},{"label":"HubSpot Knowledge Base, \"Deduplicate records in HubSpot\"","note":"documents how the HubSpot CRM finds and merges duplicate contacts and companies.","url":"https://knowledge.hubspot.com/records/deduplication-of-records"},{"label":"Google, Site Reliability Engineering, \"Monitoring Distributed Systems\"","note":"argues that every page to an on-call engineer should be actionable, the same rule a dedup window enforces on lead alerts.","url":"https://sre.google/sre-book/monitoring-distributed-systems/"}],"contributor":null,"publisher":"Artemis GTM","author":"Tom Regan","license":"https://creativecommons.org/licenses/by/4.0/","version":"2026.10","since":"2026.10","lastReviewed":"2026-10-18"}
{"@id":"https://artemisgtm.ai/resources/gtm-systems-teardown-rubric/#suppression","id":"suppression","number":4,"name":"Suppression","question":"Before any outbound send, is every recipient checked against one suppression list that holds customers, open opportunities, unsubscribes, bounces, competitors and do-not-contact requests?","failureSmell":"A current customer gets a cold first-touch email, a rep's open deal receives an SDR sequence, an address that unsubscribed in one tool is mailed by another, and suppression lives in several tool-level lists that disagree.","measurement":"Join each sequence's enrolled contacts against customer accounts, open opportunities, global_unsubscribe, hard_bounce and do_not_contact, and count the matches; the count should be zero, and any match names the gap. Stamp unsubscribed_at in every sending tool and check that an unsubscribe recorded in one tool reaches the others.","fix":"Keep one suppression ring in the system of record, and have every sending tool read it at enrollment and again just before each step sends. Write unsubscribes and bounces back to that ring from every tool, and treat a failed lookup as suppress, never as send.","patterns":["https://artemisgtm.ai/resources/gtm-systems-patterns/#suppression-ring"],"scenarios":["https://artemisgtm.ai/resources/pipeline-debugging-scenarios/#the-sequence-that-emailed-a-customer","https://artemisgtm.ai/resources/pipeline-debugging-scenarios/#the-forked-record"],"sources":[{"label":"CAN-SPAM Rule, 16 CFR Part 316 (US Federal Trade Commission, via eCFR)","note":"the US commercial email rule, which requires a working opt-out mechanism and that opt-out requests are honored.","url":"https://www.ecfr.gov/current/title-16/chapter-I/subchapter-C/part-316"},{"label":"Google, Gmail Help, \"Email sender guidelines\"","note":"sets requirements for anyone sending to Gmail accounts, including unsubscribe handling for bulk senders.","url":"https://support.google.com/a/answer/81126"}],"contributor":null,"publisher":"Artemis GTM","author":"Tom Regan","license":"https://creativecommons.org/licenses/by/4.0/","version":"2026.10","since":"2026.10","lastReviewed":"2026-10-18"}
{"@id":"https://artemisgtm.ai/resources/gtm-systems-teardown-rubric/#consent-and-region","id":"consent-and-region","number":5,"name":"Consent and region","question":"Does visitor identification respect the visitor's region: opt-out in the United States, opt-in everywhere else, and never person-level in the EEA, the UK or Switzerland?","failureSmell":"The identification script loads before the region is known, European visitors arrive in the alert channel as named people, a Global Privacy Control signal is ignored, and nobody can say which rule applied to which identified visit.","measurement":"For each identified visit, log region (us, eea_uk_ch, other or unknown), consent_state at the moment of identification, gpc_signal and identification_level (company or person). Count person-level rows where region is eea_uk_ch, rows identified before consent outside the US, rows identified while gpc_signal was true, and rows with region unknown that ran anything beyond the consent-first default. Each count should be zero.","fix":"Resolve the region first and gate every identification script and enrichment call on it: in the United States run by default and stop on an opt-out or a Global Privacy Control signal; everywhere else wait for consent; in the EEA, the UK and Switzerland stay company-level even after consent; when the region is unknown, apply the consent-first rules. Write region and consent_state onto the record so the rule that applied can be audited later.","patterns":["https://artemisgtm.ai/resources/gtm-systems-patterns/#consent-gated-identification"],"scenarios":["https://artemisgtm.ai/resources/pipeline-debugging-scenarios/#the-invisible-visitor"],"sources":[{"label":"European Data Protection Board, Guidelines 2/2023 on the technical scope of Art. 5(3) of the ePrivacy Directive","note":"sets out which tracking techniques fall under the ePrivacy consent rule.","url":"https://www.edpb.europa.eu/documents/guideline/guidelines-22023-on-technical-scope-of-art-53-of-eprivacy-directive_en"},{"label":"Global Privacy Control","note":"the browser signal a visitor uses to send an opt-out of the sale or sharing of their data.","url":"https://globalprivacycontrol.org/"}],"contributor":null,"publisher":"Artemis GTM","author":"Tom Regan","license":"https://creativecommons.org/licenses/by/4.0/","version":"2026.10","since":"2026.10","lastReviewed":"2026-10-18"}
{"@id":"https://artemisgtm.ai/resources/gtm-systems-teardown-rubric/#enrichment-waterfall","id":"enrichment-waterfall","number":6,"name":"Enrichment waterfall","question":"When the first enrichment provider returns nothing or a stale value, does the record fall through to the next source in a fixed order, with the source and date of every field recorded?","failureSmell":"Records sit with a blank title, company size or industry because one provider missed, sequences go out with a generic greeting or the wrong persona copy, and nobody can tell which vendor supplied a field or when.","measurement":"For each field that drives routing, scoring or copy (job_title, employee_count, industry, email), compute the fill rate by source and by month, and count records where field_source or field_enriched_at is null. Record email verification status at send time, not at import.","fix":"Order providers per field, call the next provider only when the previous one returns empty or falls below a confidence floor, and stop at the first verified value. Write field_source and field_enriched_at beside each value, and send records that exhaust the waterfall to a review queue instead of into a sequence.","patterns":["https://artemisgtm.ai/resources/gtm-systems-patterns/#enrichment-waterfall-with-fallback"],"scenarios":["https://artemisgtm.ai/resources/pipeline-debugging-scenarios/#the-silent-sequence","https://artemisgtm.ai/resources/pipeline-debugging-scenarios/#the-wrong-list"],"sources":[],"contributor":null,"publisher":"Artemis GTM","author":"Tom Regan","license":"https://creativecommons.org/licenses/by/4.0/","version":"2026.10","since":"2026.10","lastReviewed":"2026-10-18"}
{"@id":"https://artemisgtm.ai/resources/gtm-systems-teardown-rubric/#crm-write-back-and-reporting","id":"crm-write-back-and-reporting","number":7,"name":"CRM write-back and reporting","question":"Does every step write its timestamp and outcome back to the CRM record, against one shared handoff definition, so the funnel report is computed from fields instead of rebuilt from tool dashboards?","failureSmell":"Marketing and sales report different MQL counts for the same month, response time cannot be computed because only the create date is stored, and accepted, rejected and recycled leads look identical in the CRM.","measurement":"Check that each inbound record carries lead_created_at, alert_sent_at, claimed_at and first_touch_at, plus mql_at and either sql_accepted_at or sql_rejected_at with a rejection_reason. Count records that reached a later stage with an earlier timestamp missing, and compare the MQL count in the CRM with the count each tool reports for the same window.","fix":"Agree one written MQL-to-SQL definition with entry criteria, exit criteria and a fixed list of rejection reasons, and make it the only thing that moves lifecycle stage. Have every tool write its timestamp to the shared record instead of its own log, then build the funnel report from those fields alone.","patterns":["https://artemisgtm.ai/resources/gtm-systems-patterns/#four-timestamp-write-back","https://artemisgtm.ai/resources/gtm-systems-patterns/#shared-handoff-definition"],"scenarios":["https://artemisgtm.ai/resources/pipeline-debugging-scenarios/#the-dropped-handoff","https://artemisgtm.ai/resources/pipeline-debugging-scenarios/#the-alert-nobody-owns","https://artemisgtm.ai/resources/pipeline-debugging-scenarios/#the-cold-middle"],"sources":[{"label":"HubSpot blog, \"How to create a service level agreement (SLA) for better sales and marketing alignment\"","note":"a guide to writing the shared sales and marketing agreement that a handoff definition formalizes.","url":"https://blog.hubspot.com/blog/tabid/6307/bid/34212/how-to-create-a-service-level-agreement-sla-for-better-sales-marketing-alignment.aspx"}],"contributor":null,"publisher":"Artemis GTM","author":"Tom Regan","license":"https://creativecommons.org/licenses/by/4.0/","version":"2026.10","since":"2026.10","lastReviewed":"2026-10-18"}
{"@id":"https://artemisgtm.ai/resources/gtm-systems-teardown-rubric/#verification-loop","id":"verification-loop","number":8,"name":"Verification loop","question":"Is there a scheduled end-to-end test that pushes a synthetic lead through the live system and checks every expected outcome, so a break is found by the test and not by a buyer?","failureSmell":"A workflow stopped silently after a token expired or a field was renamed, the team found out from a lost deal or a complaint, and \"it worked when we launched it\" is the only evidence that it works now.","measurement":"Keep a list of expected outcomes for a tagged test record (record created, owner_id set, alert posted, sequence enrolled or suppressed, timestamps written) and run it against production on a schedule. Log verify_run_at, the result of each expected outcome and the time since the last fully passing run, and alert when an outcome fails or a scheduled run does not happen.","fix":"Seed tagged test records that exercise each path, such as a fit inbound lead, a customer that must be suppressed and a visitor from a consent-first region, and assert every outcome after each run. Exclude the test tag from reporting, and treat a failed or missing run as an incident with an owner.","patterns":["https://artemisgtm.ai/resources/gtm-systems-patterns/#verify-loop","https://artemisgtm.ai/resources/gtm-systems-patterns/#read-only-audit-pass"],"scenarios":["https://artemisgtm.ai/resources/pipeline-debugging-scenarios/#the-invisible-visitor","https://artemisgtm.ai/resources/pipeline-debugging-scenarios/#the-sequence-that-emailed-a-customer","https://artemisgtm.ai/resources/pipeline-debugging-scenarios/#the-same-page-for-everyone"],"sources":[{"label":"Google, Site Reliability Engineering, \"Monitoring Distributed Systems\"","note":"separates black-box monitoring, which tests behavior the way a user sees it, from white-box monitoring of internals.","url":"https://sre.google/sre-book/monitoring-distributed-systems/"}],"contributor":null,"publisher":"Artemis GTM","author":"Tom Regan","license":"https://creativecommons.org/licenses/by/4.0/","version":"2026.10","since":"2026.10","lastReviewed":"2026-10-18"}
