Status: Target Architecture
Audience: Product, Engineering, Tagging Teams
Date: 2026-06-15
Multiple Tagging Teams
├── Team A: Uses satellite.track("event_name", data)
├── Team B: Uses window.digitaldata = {...} (server-side injection)
├── Team C: Uses window.digitaldata = {...} (client-side mutation)
└── Team D: Custom event helpers
All paths lead to → Adobe Launch → Adobe Analytics
Problem: Same event tracked 4 different ways. Regressions happen when shared code changes.
One Unified Contract Layer
↓
One Analytics SDK (tiny wrapper)
├── Option A: Call satellite.track correctly
├── Option B: Inject window.digitaldata correctly
└── Option C: Both (policy decides)
↓
One Dispatch Path to Adobe Launch
↓
Production Validation and Monitoring
Contract First
packages/@analytics/contracts.One Entry Point
analytics.track(eventName, payload).Market and Brand Overlays
File: packages/@analytics/contracts/events/search-filter.ts
import { z } from "zod";
export const SEARCH_FILTER_APPLIED = {
name: "SEARCH_FILTER_APPLIED",
version: "1.0.0",
schema: z.object({
filterId: z.string(),
filterValue: z.string(),
vehicleType: z.enum(["sedan", "suv", "truck"]),
market: z.enum(["us-en", "ca-en", "za-en"]),
timestamp: z.number(),
}),
};
File: apps/@nvc/search/components/filterPanel.tsx
import { analytics } from "@analytics/sdk";
import { SEARCH_FILTER_APPLIED } from "@analytics/contracts";
export function FilterPanel() {
const handleFilterChange = (filter) => {
analytics.track(SEARCH_FILTER_APPLIED.name, {
filterId: filter.id,
filterValue: filter.value,
vehicleType: "sedan",
market: "za-en",
timestamp: Date.now(),
});
};
return <div data-removed={handleFilterChange}>...</div>;
}
File: packages/@analytics/sdk/index.ts
import { SEARCH_FILTER_APPLIED } from "@analytics/contracts";
export function track(eventName: string, payload: any) {
// Validate against contract
const contract = getContract(eventName);
const validated = contract.schema.parse(payload); // throws if invalid
// Apply tenant/market overlay
const enriched = applyMarketPolicy(validated);
// Dispatch via policy
const policy = getDispatchPolicy(eventName);
if (policy === "satellite") {
window._satellite?.track(eventName, enriched);
} else if (policy === "dataLayer") {
window.digitaldata.push({
event: eventName,
data: enriched,
});
}
// Log for observability
logEvent(eventName, enriched);
}
Add analytics for search filter events in South Africa market. Events: filter-apply, filter-clear, filter-reset. Include filter ID, value, and result count.
Creates Contract
Updates Market Policy
Generates SDK Usage in App
Generates Tests
Opens PR
You approve. Done.
Week 1-2: Foundation
packages/@analytics/contractspackages/@analytics/sdkWeek 3-4: Consolidate
Week 5-6: Agent Setup
Week 7+: Autonomous
| Phase | Effort | Timeline | You Get |
|---|---|---|---|
| Foundation | Med | 2 weeks | Contract + SDK framework |
| Consolidation | Med | 2 weeks | Teams migrated to one SDK |
| Agent MVP | High | 4 weeks | Prompt → PR for new events |
| Production-Ready | Med | 2 weeks | Drift detection + auto-merge policy |
| Total | 10 weeks | Full autonomous delivery |
| Metric | Before | After |
|---|---|---|
| Time to add market to event | 1-2 days | 1 PR (2 hours) |
| Analytics regression rate | 2-3 per month | < 1 per month |
| Regression root cause identified | 3-5 days | Auto-detected in 1 hour |
| Cross-team event consistency | 60% | 99% |
| Manual coding per feature event | 4-6 hours | 0 hours |
Once foundation is live, the agent works like this:
User: "Add tracking for loan calculator in US and ZA"
Agent: "I found calculator in nvc/financing. Need clarification:
1. Should we track open, input-change, and submit? (yes/no)
2. Include loan amount and term as payload? (yes/no)"
User: "yes, yes"
Agent: ✓ Generates contracts ✓ Updates policies ✓ Generates code
✓ Generates tests ✓ Opens PR
You: Review (2 mins) → Approve
System: Merge + Deploy + Monitor
One SDK, many dispatch options.
(Answers help agent understand existing patterns and generate compatible code.)
(Answers help prioritize agent features.)
Today: Multiple teams, multiple approaches, fragile shared code, regressions when shared code changes.
Tomorrow: One contract, one SDK, one entry point. Agent generates code, validates with tests, delivers PR. Teams never manually code analytics again. Market rollouts are config changes, not code reviews.
Result: Faster, more reliable, fewer regressions, less manual work.