Status: Complete for offline integration and contract verification
Completed: 2026-07-12
Live validation: Not part of release verification; operator approval is required
Public publication: Published 2026-07-13 as a new clean-history public repository at https://github.com/krusemediallc/cursor-ad-agent (orphan snapshot commits only). The private source repository remains separate and private, with its full development history untouched.
The repository now provides a human-approved workflow for:
competitor and first-party research
→ ranked opportunities and one-variable test plan
→ Arcads creative generation or cloning
→ claim-aware Meta copy
→ account, campaign, and ad-set selection
→ PAUSED deployment
→ separately confirmed activation
→ read-only performance polling
→ measured next-test recommendation
The orchestrator is a Cursor-executed skill and contract, not a background service or unattended spend bot. Generation, paid API usage, Meta mutations, activation, and measurement thresholds remain separate approval gates.
skills/ad-agent-orchestrator/defines the S0–S11 lifecycle and G1–G10 approval gates.- Gate receipts bind approval to a scoped artifact hash; changing the scope invalidates the receipt.
scripts/lib/ad_agent_lineage.pyrecords append-only lifecycle events and compiles per-run manifests.- Real deploys use
--run-id, allowing activation and performance snapshots to join the same provenance chain. - Resume rules require reconciliation of remote IDs and local events before a side effect can be retried.
skills/competitor-ad-research/resolves Meta Pages conservatively, preserves copy and Ad Library provenance, deduplicates by library ID, ranks adaptation readiness, and emitsBRIEF.mdhandoffs.- Base pulling uses
requests; Selenium, webdriver-manager, and Chrome/Chromium are optional and only needed for creative extraction. - Ad longevity is explicitly treated as a proxy, not evidence of performance.
skills/human-ad-copy/provides reusable direct-response frameworks, a claim/receipt workflow, and deterministic validation for Metacopy.json.- Writing heuristics and AI-tell warnings are review aids; they do not prove authorship.
shared/skills/meta-ad-builder/supports destination discovery, existing ad-set deployment, PAUSED CBO/ABO structure creation, image/video upload, provenance output, and a separate status command.- Campaigns, ad sets, and ads have no ACTIVE creation path.
- Status changes preview by default. A real ACTIVE mutation requires
--execute --confirm ACTIVATE. - Successful deployments and activations can append
ad.deployedandad.activatedlineage events.
skills/meta-performance-loop/reads Meta Insights without mutating status, budget, campaign structure, or creative.- It requires an exact conversion action type and operator-supplied thresholds.
- It emits deterministic
insufficient-data,winner,loser, orwatchclassifications with cited next-test recommendations. - Scheduling examples are documentation only; no cron or launchd job is installed automatically.
The cross-component maintainability refactor is complete:
scripts/lib/meta_graph.pyis the canonical Meta Graph HTTP transport for Marketing API operations, Ad Library research, and Insights polling. It centralizes bounded retries, credential-safe errors, pagination, and next-URL validation.- The former monolithic
meta_api.pywas split into focusedmeta_http,meta_upload,meta_structure, andmeta_listingmodules.meta_api.pyremains a thin compatibility re-export for existing imports. scripts/_bootstrap.pyand package__init__.pyfiles replaced duplicated dynamic lineage loaders with one normal import path.- The performance loop now uses the shared Graph transport and maps transport failures into its domain error without exposing credentials.
scripts/lib/public_data.pyprovides one recursive credential-pattern validator for gate receipts, lineage events, and compiled manifests.
This closes the review findings around duplicated Graph behavior, transport drift, dynamic import repetition, and growth toward a thousand-line API module.
- Meta campaigns, ad sets, and ads are created PAUSED.
- Every real deploy is preceded by a dry-run and target confirmation.
- ACTIVE is a separate operator action with exact
--execute --confirm ACTIVATE. - Orchestrated ACTIVE execution requires an approved G9 receipt ID and verifies the receipt's current scope before making the Meta request.
- An ACTIVE ad cannot deliver if its campaign or ad set is still PAUSED; the operator must review the complete hierarchy and budget.
- Real deploys should include
--run-id; without it, the performance loop cannot automatically resolve the deployment lineage. - Still-image defect correction is capped at two retries after the initial attempt. Retry credit exposure is disclosed before generation. Strategic regeneration, videos, and exhausted retry caps require fresh approval.
- Performance polling is read-only.
- Gate receipts, lineage events, and manifests reject credential-like keys and values before persistence.
- If activation succeeds but lineage append fails, the command exits nonzero with a reconcile-before-retry warning rather than reporting clean success.
A credential-free release-gate run on 2026-07-21 passed 183 offline tests:
lineage helper 50
competitor research 18
human ad copy 20
Meta ad builder 34
Meta performance loop 27
orchestrator contracts 34
--
total 183
The credential-free release check also passed Python 3.9 parsing/compilation
for 48 files, Bash syntax for 27 files, 172 Markdown relative-link checks,
working-tree and Git-history secret scans, CLI --help contracts, and the
10-skill public-clone readiness check. The focused security review reported no
critical findings.
These checks used mocks, fixtures, and temporary directories. They did not generate Arcads assets, scrape competitor creatives, create or activate Meta entities, poll live Insights, or make paid API calls.
The following surfaces have offline/mock coverage but are not represented as operator-approved live validation:
- Meta campaign and ad-set creation payloads;
- multi-account destination listing;
- chunked Meta video uploads;
- Meta status changes and activation;
- Meta Insights polling; and
- competitor Ad Library creative extraction.
Live checks require explicit account-operator approval. Start with read-only destination discovery or a known deployed-ad Insights query. Keep all mutation checks behind preview/dry-run and the existing confirmation gates. Do not generate, scrape, deploy, or activate merely as a release smoke test.
These are non-blocking boundaries, not completed guarantees:
- Entity IDs are checked for non-empty input but do not have a numeric-format precheck before a Graph request.
- A standalone activation without
--run-iddoes not participate in orchestrator G9 receipt verification or append activation lineage. It still requires exact--execute --confirm ACTIVATE. - Credential-pattern validation is defense in depth, not a general-purpose secret scanner; operators must still keep secrets out of persisted values.
Use a maintained Python installation backed by a current OpenSSL for live Meta or Selenium work. Keep optional browser dependencies out of the default setup.
For setup and operating boundaries, see README.md. For offline test commands and source provenance, see CONTRIBUTING.md. For credential handling and responsible disclosure, see SECURITY.md.