diff --git a/docs/oss-contributions/README.md b/docs/oss-contributions/README.md index e79c0ad..d0862aa 100644 --- a/docs/oss-contributions/README.md +++ b/docs/oss-contributions/README.md @@ -16,9 +16,12 @@ A proposal is not a reason to close an upstream issue automatically. Maintainers own issue state and may prefer a custom integration, a documentation recipe, a native admin surface, or no change. +See the [six-issue review](./six-issues-review.md) for the current maintainer-first +selection, validation boundary, and cross-project lessons. + ## Verified status -Status checked against the GitHub API on **2026-09-01**. +Status checked against the GitHub API on **2026-09-15**. | Record | Upstream | Status and ClickTrail-relevant outcome | |---|---|---| @@ -40,6 +43,12 @@ Status checked against the GitHub API on **2026-09-01**. | [phpList](./phplist-php-attribution-issue.md) | [#1140](https://github.com/phpList/phplist3/issues/1140) | Open; explicitly separated from outbound-link tracking issue #556. | | [Relaticle](./relaticle-provenance-issue.md) | [#531](https://github.com/relaticle/relaticle/issues/531) | Closed because ideas belong in Discussions; the recorded discussion link currently returns 404 from the API. | | [Comp AI](./comp-ai-provenance-short-note.md) | Project guidance | Short idea note only; do not post as a generated long issue. | +| [Capacita](./capacita-google-ads-closed-loop-issue.md) | [#107](https://github.com/misaeln-pc1/marketing-performance-capacita/issues/107) | Open; design-only while native Zoho integration and CRM data gaps are resolved. No runtime PR. | +| [matchXelerate](./matchxelerate-consent-utm-gclid-issue.md) | [#22](https://github.com/OS-labs-digital/matchxelerate-web/issues/22) | Open; optional Next.js consent/UTM/GCLID reference example is the smallest useful ClickTrail contribution. | +| [Hauddy](./hauddy-campaign-attribution-issue.md) | [#95](https://github.com/Hauddy/hauddy/issues/95) | Open; native source and activation events already exist. Documentation/reporting comes before an adapter. | +| [ROLANPRO](./rolan-google-ads-crm-issue.md) | [#139](https://github.com/zufarataev-code/Rolan-PRO-CRM/issues/139) and [PR #140](https://github.com/zufarataev-code/Rolan-PRO-CRM/pull/140) | Open; active draft PR already owns the CRM integration. Do not duplicate it. | +| [Vanta Labs](./vanta-google-ads-attribution-issue.md) | [#184](https://github.com/brendenhuntzinger1/vanta-labs/issues/184) | Open; latent Google source/spend classification gap with no observed Google orders. Test/mapping proposal only. | +| [CG Dynamics](./cg-dynamics-ga4-ads-issue.md) | [#335](https://github.com/CGProductionHouse/CG-Dynamics/issues/335) and [PR #336](https://github.com/CGProductionHouse/CG-Dynamics/pull/336) | Open; active PR already owns exact Ads↔GA4 reporting. Do not duplicate it. | ## ClickTrail-owned issue references diff --git a/docs/oss-contributions/capacita-google-ads-closed-loop-issue.md b/docs/oss-contributions/capacita-google-ads-closed-loop-issue.md new file mode 100644 index 0000000..807086e --- /dev/null +++ b/docs/oss-contributions/capacita-google-ads-closed-loop-issue.md @@ -0,0 +1,74 @@ +# Issue review: Capacita CRM → Google Ads conversion feedback + +Target: + +Status checked against the public issue and comments on **2026-09-15**. The issue is +open and explicitly remains design-only. The latest owner notes say to audit and +repair the native Zoho CRM ↔ Google Ads integration first; the re-authentication flow +is currently held by Google's six-day security delay. + +## Observed problem and cause + +The requested closed loop is: + +```text +Google Ads click → Capacita landing → Zoho CRM → validated commercial milestone → Google +``` + +The current evidence does not establish a missing ClickTrail adapter. It establishes a +provider and data-readiness gap: + +- GCLID reaches some CRM records. +- Campaign, ad group, keyword, click date, and cost enrichment is not populated in the + reviewed records. +- The native Zoho conversion export was observed as `Not started`. +- The Google Ads account selector in Zoho appeared empty during re-authentication. +- The issue owner has set `DESIGN_ONLY=YES`, `CRM_WRITES=0`, and + `GOOGLE_CONVERSION_UPLOADS=0` until the data gaps close. + +The issue also records a new decision: **audit native Zoho first**. A custom Data +Manager pipeline is a fallback or extension, not a reason to bypass that audit. + +## Maintainer-first contribution + +No runtime PR is appropriate yet. A useful contribution after the owner confirms the +native path would be one small, provider-neutral contract fixture or runbook covering +what the existing CRM integration must prove. It should not add a ClickTrail, Zoho, or +Google dependency to this repository. + +Suggested contract parameters: + +- allowlisted `gclid`, `gbraid`, and `wbraid` where the chosen Google path supports them; +- `utm_source`, `utm_medium`, `utm_campaign`, `utm_term`, and `utm_content` only if the + landing/form path currently receives them; +- the real CRM record ID and configured milestone, kept server-side; +- event type, actual milestone timestamp, nullable value, and currency; +- a stable non-PII transaction ID and a destination/action idempotency key; +- the capture-time consent state, source, and policy version. + +Empty identifiers must not overwrite a valid earlier touchpoint. A CRM record and its +commercial outcome remain Zoho's authority. ClickTrail could provide normalization and +capture at the trusted form boundary, but it must not decide what “matrícula” or “venta +real” means. + +## Boundaries and stop conditions + +- Do not send CRM PII, hashes, tokens, or real payloads to GitHub or an agent. +- Do not create CRM writes, Google uploads, account changes, or conversion actions from + this contribution. +- Do not mark an HTTP response as Google processing proof; require destination + diagnostics and reconciliation. +- Do not choose `PRIMARY_CONVERSION`, monetary value, reversal rules, or B2C/B2B + mapping until the owner supplies the real Zoho fields and business decision. +- Do not add a duplicate custom pipeline while native Zoho is still unresolved. + +## Acceptance before implementation + +1. Native Zoho account association and auto-tagging are read-only verified. +2. The actual lead/contact/deal fields and CRM milestones are mapped. +3. Google conversion action IDs and the supported ingestion path are confirmed. +4. Consent, deduplication, reversals, expiry, and CRM↔Google reconciliation are written + down. +5. A validate-only synthetic fixture passes without mutating CRM or Google. + +**Disposition:** design record only; no ClickTrail runtime integration or host PR. diff --git a/docs/oss-contributions/cg-dynamics-ga4-ads-issue.md b/docs/oss-contributions/cg-dynamics-ga4-ads-issue.md new file mode 100644 index 0000000..d59d479 --- /dev/null +++ b/docs/oss-contributions/cg-dynamics-ga4-ads-issue.md @@ -0,0 +1,42 @@ +# Issue review: CG Dynamics Google Ads → GA4 website performance + +Target: + +Status checked on **2026-09-15**: open. PR [#336](https://github.com/CGProductionHouse/CG-Dynamics/pull/336) +is already active and covers the requested Google Ads/GA4 reporting path. It keeps Ads +provider truth separate from GA4 website behaviour and remains subject to CA-gated live +provider setup. + +## Why ClickTrail should not own this feature + +The issue is primarily a provider-reporting and exact-client mapping problem. The active +PR already addresses: + +- exact `client_id` → Ads campaign/account → GA4 property/domain mapping; +- runtime GA4 metadata validation; +- separate Ads clicks and GA4 sessions; +- truthful unavailable/setup-required states instead of fabricated zeroes; +- CTA/key-event availability and Admin Preview/client parity; +- campaign-type-aware ValueTrack guidance. + +A ClickTrail package would duplicate that reporting architecture. The only possible +ClickTrail seam is an optional event attached to a verified enquiry or CTA, if the +maintainers later identify a missing site-side event contract. + +## Parameters and boundaries + +- exact client, campaign, property, and approved domain IDs are server/config-owned; +- `gclid`/UTM context may support a deterministic enquiry join, but Ads clicks are not + equated with GA4 sessions; +- CTA names and key events come from the client’s configured taxonomy, not guessed names; +- `setup_required`, `not_tracked`, and `unavailable` must remain distinct from a real + numeric zero; +- Ads account changes, auto-tagging, Final URL suffixes, credentials, migrations, and + deployment remain CA/provider gates. + +ClickTrail must not scrape GA4, recalculate Ads clicks/spend, select a client by fuzzy +name, or claim provider delivery from a local event. + +**Disposition:** do not duplicate PR #336. Revisit only for a narrowly defined, optional +site enquiry-event recipe after the existing reporting work is merged and its owners ask +for it. diff --git a/docs/oss-contributions/hauddy-campaign-attribution-issue.md b/docs/oss-contributions/hauddy-campaign-attribution-issue.md new file mode 100644 index 0000000..f7a6e6e --- /dev/null +++ b/docs/oss-contributions/hauddy-campaign-attribution-issue.md @@ -0,0 +1,54 @@ +# Issue review: Hauddy campaign attribution and acquisition outcomes + +Target: + +Status checked on **2026-09-15**: open, with no maintainer comments. The issue's own +review names the relevant paths and records that v0.1.20 already stores aggregate +`form_start`, request, verification, invitation, claim, and activation events. + +## Observed seam and cause + +Hauddy already has a native acquisition path: + +- the landing form submits `source`; +- the backend accepts approved labels and groups other values as `campaign`; +- the first stored waitlist source is retained; +- activation is counted after an actual non-human recipient acknowledges a message. + +The unresolved problem is not “missing ClickTrail.” It is that the current model does +not document medium/campaign conventions or expose a bounded, readable report. Existing +request counters include retries, so attempts must not be read as people or verified +activation. + +## Maintainer-first contribution + +A useful first patch would be native documentation and a small aggregate report or +query, if the maintainers want those surfaces. A ClickTrail adapter should be considered +only at the existing `/preregistration/request` boundary and only if Hauddy needs a +standard first-touch envelope. It must not duplicate the waitlist or activation model. + +The minimum declared inputs are: + +- an approved `source`/campaign label from a versioned configuration; +- event name and count semantics (`form_start`, request, verification, invitation, claim, + activation); +- a time window if the maintainers later add date/cohort storage; +- a stable internal record ID for joins, never an email or token in a report. + +Do not silently turn arbitrary `utm_*` query values into campaign labels. If medium and +campaign are needed, the maintainers should define their representation and release/deploy +configuration first. + +## Boundaries and acceptance + +- Hauddy owns consent, retention, labels, waitlist records, verification, and activation + truth. +- ClickTrail would own only optional acquisition context and would not decide whether an + agent activated. +- Retries and duplicate requests must be tested separately from unique people. +- Unknown labels must follow the documented bucket and never become an unbounded taxonomy. +- Reports must contain channel, event, timeframe, and caveats, but no email, token, + message body, or credential. + +**Disposition:** native documentation/report opportunity; no ClickTrail runtime PR until +Hauddy confirms that its existing source model cannot satisfy the need. diff --git a/docs/oss-contributions/matchxelerate-consent-utm-gclid-issue.md b/docs/oss-contributions/matchxelerate-consent-utm-gclid-issue.md new file mode 100644 index 0000000..8749251 --- /dev/null +++ b/docs/oss-contributions/matchxelerate-consent-utm-gclid-issue.md @@ -0,0 +1,64 @@ +# Issue review: matchXelerate consent-aware UTM/GCLID persistence + +Target: + +Status checked on **2026-09-15**: open, with no maintainer comments. The repository's +`docs/SPEC.md` is the source of truth. It already establishes Next.js App Router, +GTM/GA4 through `src/lib/analytics.ts`, HubSpot server-side forms, and Hungarian and +English routes. + +## Observed seam + +The issue asks for four related but separable behaviours: + +1. Consent Mode v2 defaults to denied before GTM. +2. The cookie banner owns the transition to granted and remembers that choice for 180 + days. +3. Typed events carry the specified parameters, including `locale` on navigation. +4. UTM values and `gclid` survive navigation from the first landing to a later form. + +ClickTrail can help with item 4 and the server-side attachment boundary. It must not +replace the site's CMP, GTM container, HubSpot submission, or locale taxonomy. + +## Maintainer-first contribution + +The smallest useful artifact is a dependency-free Next.js reference example in +ClickTrail, plus tests for the three-page journey. It should be optional and easy to +remove. It should show both the ClickTrail path and the no-package host implementation. +No ClickTrail dependency belongs in this application unless its maintainers request +one after reviewing the existing `analytics.ts` seam. + +Recommended parameters: + +- `utm_source`, `utm_medium`, `utm_campaign`, `utm_term`, and `utm_content`; +- `gclid` and, only if the campaign setup uses them, `gbraid`/`wbraid`; +- the host-owned `locale` value on `page_view`; +- the host-owned form/event name and a server-owned lead reference. + +The issue describes the attribution cookie as session-lived. That choice should remain +with the maintainers; ClickTrail's longer default must not silently override it. The +180-day retention applies to the consent choice, not automatically to all attribution. + +## Boundaries and evidence + +- The host CMP is the consent authority. Unknown or denied consent must not persist + advertising identifiers. +- GTM remains host-owned. ClickTrail must not inject a second GTM snippet or invent + event names. +- Browser values are untrusted context. HubSpot and any lead ID are server-owned. +- No email, phone, cookie header, or raw request belongs in a data-layer event. +- “Seen in GTM Preview” proves tag wiring only; it does not prove HubSpot storage or + provider conversion delivery. + +## Acceptance for a reference example + +- `?utm_source=linkedin&utm_campaign=kickoff` survives three synthetic pages and is + present on the final `form_submit` attachment. +- Denied consent creates no advertising persistence; granting consent does not rewrite + an earlier first touch with a later campaign. +- Missing `NEXT_PUBLIC_GTM_ID` leaves the app error-free and loads no snippet. +- Both locales use the same event contract and the expected `locale` parameter. +- Tests contain synthetic identifiers only and show no raw form data in diagnostics. + +**Disposition:** strong reference-example opportunity; no host-repository code or +package installation proposed. diff --git a/docs/oss-contributions/rolan-google-ads-crm-issue.md b/docs/oss-contributions/rolan-google-ads-crm-issue.md new file mode 100644 index 0000000..193a73e --- /dev/null +++ b/docs/oss-contributions/rolan-google-ads-crm-issue.md @@ -0,0 +1,55 @@ +# Issue review: ROLANPRO Google Ads and CRM integration + +Target: + +Status checked on **2026-09-15**: open. Draft PR [#140](https://github.com/zufarataev-code/Rolan-PRO-CRM/pull/140) +is already active and contains the requested CRM-side implementation work. Its latest +checks reported success, but the PR remains draft and its live provider/account proof is +not complete. + +## Why this is not a new integration target + +The issue is a large CRM feature, not a missing browser helper. PR #140 already owns the +schema, lead attribution, conversion events, outbox, Data Manager worker, adjustments, +Customer Match, cost import, reconciliation, settings, and diagnostics lanes. Opening a +second PR would create competing business logic. + +## Useful ClickTrail boundary + +If the ROLANPRO maintainers want a ClickTrail contribution, keep it at the existing +website lead/form handoff: + +- capture `gclid`, `gbraid`, `wbraid`, approved UTM fields, landing page, supported + session attributes, and capture-time consent; +- append a touchpoint only after the server accepts the lead; +- attach it to the server-owned lead/contact ID; +- preserve a valid earlier click ID when a later request is empty; +- hand off a stable, non-PII external key to ROLANPRO's transaction/outbox service. + +ROLANPRO must remain the authority for PostgreSQL business data, deal stages, revenue, +refunds, Customer Match eligibility, credentials, and destination receipts. The canonical +sale boundary is `CLOSED_WON` after the signed agreement and required deposit; Project +creation is not another sale. A qualified-lead event must remain disabled until a real +qualified stage is configured. + +Suggested outbox contract parameters: + +- event type and actual occurred timestamp; +- nullable Decimal value and currency; +- immutable business event ID; +- destination account + action + transaction ID uniqueness; +- consent state that preserves `UNKNOWN`/`DENIED`; +- request ID, retry state, and reconciliation status. + +## Review gates + +- Business mutation and outbox row are one database transaction. +- Repeated stage updates and concurrent workers cannot duplicate the event. +- Unknown money is `NULL`, not zero or an estimate. +- Validate-only requests are not described as live delivery. +- Provider diagnostics and CRM reconciliation remain separate from ClickTrail capture + evidence. + +**Disposition:** do not duplicate PR #140. Offer an optional capture adapter or review +fixture only after the ROLANPRO maintainers identify a concrete seam that the active PR +does not already cover. diff --git a/docs/oss-contributions/six-issues-review.md b/docs/oss-contributions/six-issues-review.md new file mode 100644 index 0000000..c1a7eff --- /dev/null +++ b/docs/oss-contributions/six-issues-review.md @@ -0,0 +1,109 @@ +# ClickTrail maintainer-first review: six upstream issues + +Reviewed on **2026-09-15**. This report records the decision boundary, not upstream +adoption or provider delivery. All six host repositories reported `viewerPermission:"READ"` +for the authenticated account. ClickTrail-owned repositories are the only repositories +where a branch and draft PR are appropriate in this pass. + +## Executive decision + +- **Matchxelerate #22:** implement one optional, consent-aware Next.js reference example + in ClickTrail. Do not install ClickTrail in the host application. +- **Capacita #107:** design-only. The owner is auditing native Zoho ↔ Google Ads first; + do not add a second Data Manager pipeline or perform writes. +- **Hauddy #95:** native source and activation events already exist. Document/report the + existing seam before proposing an adapter. +- **ROLANPRO #139:** do not duplicate active draft PR #140, which already owns the CRM, + conversion outbox, Data Manager, adjustments, reconciliation, and Customer Match lanes. +- **Vanta Labs #184:** test and centralize the existing source/spend classification before + adding a Google label. No Google order or spend evidence was observed in the read-only + review. +- **CG Dynamics #335:** do not duplicate active PR #336, which already owns exact + Ads↔GA4 mapping and provider-reporting states. ClickTrail is not a replacement for + either provider. + +The detailed records are [Capacita](./capacita-google-ads-closed-loop-issue.md), +[matchXelerate](./matchxelerate-consent-utm-gclid-issue.md), +[Hauddy](./hauddy-campaign-attribution-issue.md), +[ROLANPRO](./rolan-google-ads-crm-issue.md), +[Vanta Labs](./vanta-google-ads-attribution-issue.md), and +[CG Dynamics](./cg-dynamics-ga4-ads-issue.md). + +## Shared contract + +ClickTrail is useful only at the acquisition-context boundary: + +```text +landing query → consented first-party context → server form handoff → host outbox +``` + +The smallest provider-neutral envelope is: + +- `gclid`, `gbraid`, `wbraid`; +- `utm_source`, `utm_medium`, `utm_campaign`, `utm_term`, `utm_content`; +- landing route without the query string; +- capture time and consent snapshot/policy version; +- a host-owned stable lead/order/event ID when the server accepts the record. + +Every value is untrusted, allowlisted, and bounded. Empty values do not overwrite a +valid first touch. PII, credentials, cookies, raw requests, arbitrary JSON, and provider +responses are outside this envelope. + +The host remains the authority for: + +- consent, retention, deletion, and access control; +- CRM/database records and joins; +- lifecycle milestones, revenue, refunds, and reversals; +- destination credentials, account/action IDs, and request contracts; +- outbox atomicity, retries, idempotency, reconciliation, and diagnostics. + +A conversion value is nullable. If present, its currency and actual event timestamp are +required. A local payload builder or successful queue insert is not proof that Google, +Zoho, HubSpot, Meta, GA4, or another provider accepted or reported the event. + +## No-package fallback + +A host does not need a ClickTrail dependency. Its existing middleware or cookie utility +can implement the same allowlist, bounds, affirmative-consent gate, first-touch rule, and +server attachment. If the host cannot establish those controls, the safe fallback is not +to persist the identifier and not to add a package. + +## Validation performed + +- The corrected Next.js example uses synthetic IDs and `.test` addresses only. +- `npm test` in `nextjs-google-ads-offline-conversions`: **9 passed**. +- `npm run typecheck` in the same example: **passed** after adding the missing React and + Node type dependencies and JSX compiler setting. +- `git diff --check`: passed for the example and this documentation worktree. +- No command in this contribution calls Google, Zoho, CRM, GTM, Data Manager, Ads, or a + live host application. + +These checks prove local structure and policy behaviour only. They do not prove consent +legality, provider matching, campaign attribution, CRM storage, or production readiness. + +## Lessons for maintainers + +1. **Validate the host seam first.** A native source field or reporting path is often + better than a new dependency. +2. **Do not confuse capture with commercial truth.** Click IDs identify acquisition + context; only the host can define a qualified lead, activation, closed sale, refund, + or reversal. +3. **Keep provider roles separate.** Google Ads spend/clicks, GA4 behaviour, CRM stages, + and ClickTrail deterministic handoff data must not be silently merged or treated as + interchangeable. +4. **Fail closed.** Unknown or denied consent, missing configuration, missing spend, and + unavailable provider data must remain explicit states rather than guessed defaults. +5. **Prefer a small fixture or guide.** A synthetic lifecycle test and no-package recipe + are safer first contributions than a core schema, migration, provider client, or live + upload. +6. **Do not duplicate active work.** Existing upstream PRs #140 and #336 remain the + owners of their respective host implementations. + +## Remaining risks + +- Provider-specific Google Ads and Data Manager field contracts still require an owner-led + account and validate-only check. +- Cookie retention, consent categories, and lawful basis are host policy decisions. +- Browser click IDs can be absent, malformed, expired, or spoofed. +- The example does not implement a CRM, outbox, queue worker, or provider client. +- Upstream issue and PR states can change after this review date. diff --git a/docs/oss-contributions/vanta-google-ads-attribution-issue.md b/docs/oss-contributions/vanta-google-ads-attribution-issue.md new file mode 100644 index 0000000..1865126 --- /dev/null +++ b/docs/oss-contributions/vanta-google-ads-attribution-issue.md @@ -0,0 +1,52 @@ +# Issue review: Vanta Labs Google Ads attribution path + +Target: + +Status checked on **2026-09-15**: open, with no maintainer comments. The issue explicitly +calls this a latent gap, not a current reporting defect. + +## Observed cause + +The repository has two classification paths that can disagree when Google traffic first +converts: + +- `is_paid_ad_source()` admits the four currently purchased platforms or a platform with + recorded spend; Google is in neither set. +- `resolveMarketingSource()` already treats a `gclid` branch as an ad signal. +- Google Ads is present in the website tag and `gclid` is stored in order attribution, + but the downstream paid-source and spend path does not consume it. +- The owner’s read-only check found zero orders with `gclid`, zero Google-like UTM sources, + and zero Google spend rows. Existing values were `null`, `chatgpt.com`, and `tiktok`. + +Adding `google` to one list would therefore be an incomplete and unsafe fix. Revenue could +appear under a paid label without a Google spend row, creating an invalid ROAS comparison. + +## Maintainer-first contribution + +The smallest useful change is a repository-native contract test or mapping helper that +makes the SQL predicate and TypeScript resolver agree. It should wait for the maintainer +to decide: + +- whether a click ID alone is sufficient paid evidence when source is absent; +- the canonical key for `google`, `google_ads`, and `adwords`; +- where the mapping is owned so SQL and `utm.ts` cannot drift; +- which `WINDSOR_CONNECTORS` capacity is available; +- how Google spend is ingested before revenue is included in ROAS. + +ClickTrail can optionally capture and carry the allowlisted click ID, but it must not +classify an order as paid, manufacture spend, or calculate commercial ROAS for Vanta. + +## Parameters and acceptance + +- canonical source mapping and its test vectors; +- `gclid`/UTM first- and last-touch fields; +- Google account/campaign spend rows with date and currency; +- order attribution join key and provider-native order value; +- an explicit “not measured” state when spend is absent. + +Acceptance is one classification for every order, Google revenue and Google spend on the +same reporting row, and no ROAS until both provider-native inputs exist. The current +under-claiming behaviour is safer than adding an unverified Google label. + +**Disposition:** audit/test opportunity; no ClickTrail host PR and no Google connector +change until spend and source rules are confirmed.