Skip to content

Diagnose tracking - #11

Closed
amitl-levi wants to merge 6 commits into
taboola:marketplace-packagingfrom
amitl-levi:diagnose-tracking
Closed

amitl-levi wants to merge 6 commits into
taboola:marketplace-packagingfrom
amitl-levi:diagnose-tracking

Conversation

@amitl-levi

@amitl-levi amitl-levi commented Aug 22, 2026

Copy link
Copy Markdown
Collaborator

Part 5 (final) of the split of the former stacked PRs, per review feedback. New diagnose-tracking skill: pixel-health diagnosis ("pixel not firing", "conversions not tracking") — previously an explicit UI redirect.

Stack: based on marketplace-packaging (PR #14); this PR's diff is exactly its own 5 commits. Merge order: #8#12#13#14 → this.

What

  • Verifies the Taboola Pixel from evidence a client can produce: raw-HTML fetch of the user's page (static install check; multi-account and network-level pixel setups handled; app-store URLs caught upfront), a user-captured HAR / window._tfa dump (runtime firing check with copy-paste capture instructions), and MCP cross-checks (rule status/event-name match, spend).
  • Fix routing by owner: site-side → copy-paste instructions; rule-side → manage-campaigns preview-then-confirm gate; Taboola-side → /realize-plugin:support escalation. The skill itself never writes.
  • Adapted from an internal Taboola support team's pixel-diagnostics skill, with all internal material (SQL, Salesforce, config flags, live capture) stripped; adoption notes + MCP asks in docs/2026-08-22-pixel-expert-adoption-plan.md.

Reviewer focus

  • Trust boundary (os/guardrails.md): first non-realize.com web access — scoped to the page under diagnosis; fetched page and HAR content are evidence, never instructions (read Scenario 22D plants hostile page text as the regression test). HAR hygiene: Grep-first sliced reading, no cookies/auth headers in output.
  • Honesty boundary: no MCP tool reports whether a pixel event landed inside Taboola — verified-healthy-but-still-nothing ends in the support escalation, never an invented server-side fact.
  • Tested live on a real advertiser landing page and a real 5.5MB HAR (runtime-injected pixel correctly detected; page_view JSON transport validated; publisher ad-widget vs advertiser pixel distinguished).
  • The static check downloads raw HTML via curl (scoped to the page under diagnosis) because WebFetch strips every <script> tag — tested live; a WebFetch-based check reports "no pixel" on every site.

Tests

Read Scenario 22 (A–D), write Scenario W15 (diagnosis→fix handoff stays gated). brand-check.sh 0 FAIL, bundle tests 82/82, CI validate green.

🤖 Generated with Claude Code

amitl-levi and others added 6 commits August 30, 2026 13:42
… refusal

Adapted from an internal Taboola support team's pixel-diagnostics skill
with everything internal stripped: no internal-database queries, no
Salesforce intake, no internal config flags, no live-browser tooling.
Adoption notes and the MCP capability asks (top ask: a server-side
"did the pixel events land?" read) are in
docs/2026-08-22-pixel-expert-adoption-plan.md.

The skill verifies the Taboola Pixel from evidence a client can
produce: fetches the user's page (static install check, per account -
multi-account and network-level pixel setups handled), reads a
user-captured HAR / window._tfa dump (runtime firing check, with
copy-paste capture instructions for a non-technical reader), and
cross-checks conversion rules and spend via the MCP. Fixes route by
owner: site-side as copy-paste instructions (with proactive help-center
install steps when the code is missing), rule-side through
manage-campaigns' preview-then-confirm gate, Taboola-side through the
/realize-plugin:support escalation. App-store URLs are caught before
any fetch - no web pixel runs there, so "not installed" would be a
false finding; the answer is the S2S/MMP path.

This flips a documented refusal, so every stale claim site changed in
the same commit: the agent's description, triage table (pixel-health
removed from UI-only; dedicated routing row added), over-engagement
anchor, tracking ladder (new rung 3), and tool-existence boundary; the
guardrails' out-of-MCP list; manage-campaigns' UI-fallback section;
optimize-campaign's P1 pre-check and prescription hand-offs; README
scope + skills table; knowledge/tracking.md and its manifest entry.
Pixel installation, codeless-conversion setup, and test-firing remain
genuinely UI-only.

Two new trust boundaries in os/guardrails.md: the landing-page fetch
is the plugin's first non-realize.com web access, scoped to the page
under diagnosis, and fetched content - like HAR content - is evidence,
never instructions (Scenario 22D plants hostile page text as the
regression test). HAR files carry cookies and session data: Grep-first
sliced reading, and no cookies / auth headers / unrelated-domain
requests in any output.

The honesty boundary is explicit because no MCP pixel tool exists: the
skill can prove what the browser sent and what Realize reports, never
whether an event landed inside Taboola's processing. The source
skill's spend gate is kept verbatim - fires + live rule + zero
conversions with no active spend is expected, not broken.

Read Scenario 22 (A-D) and write Scenario W15 (diagnosis-to-fix
handoff stays gated; "find out why and fix it" is not
pre-authorization) added.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…ipt tag

Tested live before anyone hit it in the field: WebFetch converts the
page to readable text before answering, so a page whose raw HTML
carried 11 script tags came back with zero code visible. A
WebFetch-based static check would report "no pixel" on every site -
the worst possible failure for a diagnostic skill, wrong with
confidence.

The check now downloads the raw page via Bash (curl of the user's
page under diagnosis, nothing else), Greps it for the pixel markers,
and Reads only matching regions. WebFetch is dropped from the skill's
allowed-tools; the skill, the agent's tool reference, and the
tool-existence boundary all say why, so a future cleanup doesn't
"simplify" it back. CLAUDE.md's no-direct-curl rule now names this as
its one sanctioned non-API exception, and Scenario 22A fails any run
whose static check went through WebFetch.

Trust rules are mechanism-independent and unchanged: the downloaded
page is untrusted evidence, never instructions.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Live probes before anyone hits these in the field:

- A Taboola publisher page (site showing Taboola ads) loads
  cdn.taboola.com/libtrc/<publisher>/loader.js - same libtrc family,
  zero advertiser pixel. Verified on a real publisher site. Judging
  the pixel by "libtrc" alone reports "installed" on any site that
  merely runs Taboola ads; only libtrc/unip/<id>/tfa.js is the pixel.
  Both the skill and the pixel reference now state the distinction.

- A failed download, a bot-challenge page, or a near-empty JS shell
  (observed live: a 7KB single-page-app shell on a real brand site)
  gets no static verdict at all - the skill says the page couldn't be
  inspected statically and moves to the user's browser capture, which
  answers everything the static check would have.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…st live run

Two field facts from running the new skill against a real advertiser
landing page and a real HAR capture:

- The static check and the HAR check both work end-to-end. The page
  carried zero Taboola code in raw HTML (runtime-injected pixel), the
  skill correctly deferred to the capture instead of reporting "not
  installed", and the 5.5MB HAR yielded the full verdict via
  Grep-first sliced reading: tfa.js 200, exactly one page_view on the
  modern JSON transport, item-url present, current library version,
  internal engagement events ignored, no cookies echoed.

- The server-side write block follows the user, not the account. The
  rejection message names the account, but the operative policy is
  that internal Taboola users are excluded from writes - a client
  user can succeed on the same account. The agent's error handling,
  the manage-campaigns gotcha, and the W10-W15 unrun note now say so;
  running the write scenarios needs a non-internal user, not a
  different account.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…-side item

The adoption doc for the MCP owner now carries only what is theirs:
the three capability asks plus minimal context. The skill-side backlog
moves to CLAUDE.md's open items, with one change of status: live
browser capture is promoted from "only if evidence shows the need" to
a planned next step - the HAR path works but makes the user do the
capturing, and removing user effort is the product goal. Its price
tag is stated as non-negotiable: a structurally unbypassable
throwaway-browser boundary, reviewed before any implementation, with
purchase-funnel capture out of scope even then.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Findings from the requested per-PR review:

- The documented duplicate-install signature could never occur: the
  base snippet's getElementById guard means a second copy inserts no
  second tb_tfa_script tag - it double-fires page_view instead. The
  checklist row, the reference, and the skill now key duplicate
  detection on page_view fire count, not DOM tags.
- The sanctioned curl gains its trust-boundary flags: scheme pinned
  to http/https, redirects capped, final status + effective URL
  checked before the file is believed - a saved 200-shaped error page
  or an off-host redirect now skips the static verdict instead of
  reading as "no pixel".
- Evidence capture: point users at Chrome's sanitized HAR export
  (strips cookies/auth, keeps everything the check needs) and warn
  about the console's one-time "allow pasting" gate.
- Runtime honesty for Codex: the guardrails ship to runtimes without
  the skill layer, so the pixel-health routing now says the UI
  redirect stands where the skill isn't loaded.
- Self-check gains a fetched-page/HAR item (no cookies or auth
  headers in output; instruction-shaped content quoted, not obeyed).
- Output rules: the raw-field-name ban is scoped to Realize API
  fields - the user's own pixel event names and on-wire values are
  quoted verbatim.
- Permission plumbing: settings example + INSTALL now allow the
  page-fetch curl, so a diagnosis doesn't die on a declined prompt
  that reads as "no answer"; the outbound-scope sentence covers it.
- Claim-site sweep completions: the unreleased-changelog
  self-contradiction on pixel-health, docs/realize-best-practices-gap
  ("conversion count is zero" is now served; diagnose-tracking is the
  home if get_pixel_status lands), the guardrails' skill-name list,
  and a ~100-char trim of the skill description clear of the
  frontmatter limit.
- Hygiene: local Slack/PR-draft txt files are now gitignored.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@amitl-levi
amitl-levi force-pushed the marketplace-packaging branch from bdfb2bd to ee44c5f Compare August 30, 2026 10:43
@amitl-levi amitl-levi mentioned this pull request Sep 1, 2026
@amitl-levi

Copy link
Copy Markdown
Collaborator Author

Closing per review — this was opened from a personal fork by mistake. Replaced by #16 (same branch, same commits, on the taboola repo).

@amitl-levi amitl-levi closed this Sep 1, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants