Skip to main content

DOC1 — Apple Ads documentation sync

Branch: sam/dev-2080-docs-sync. The delivery commit SHA is supplied in the executor’s final report; this file is part of that commit. Source snapshots verified from fetched origin/main:
  • dash-mono 05417021b31c906874451a0ac39559b7e98dd810
  • api-gateway 11b625e7cddb388cd6f6eb92b225bd3e9da6b8c9
  • Documentation base 6c25bd6.

Files and purpose

  • api-reference/rest-api-v4.yaml — Unified refusal schemas with required type/code/message, JSON 413 with either idempotency path, and public disconnect compatibility.
  • reference/v4/apple-ads.mdx — Aligned error codes/envelope and 413; explained public disconnect state and OAuth/legacy recovery.
  • docs/apple-ads-attribution.mdx — Updated three display labels while keeping stored values intact.
  • docs/apple-search-ads.mdx — Separated explicit Disconnected from Apple-side Expired or revoked; corrected Connect with Apple action.
  • docs/apple-ads-troubleshooting.mdx — Aligned disconnect, Enable/Pause outcome copy, and stale-permission recovery.
  • docs/apple-ads-budget-usage.mdx — Gave Far below the budget its dedicated bids/targeting/delivery advice.
  • docs/apple-ads-manage-campaigns.mdx — Documented campaign switch vs child-row menu, keyword-only Set bid, Enable/Pause labels, and OAuth/legacy recovery; kept old heading anchors.
  • docs/apple-ads-data-freshness.mdx — Clarified import preview dates cover added rows and spend is grouped by currency.
  • docs/mcp-apple-ads.mdx — Corrected OAuth vs legacy stale-permission recovery.
  • skill.md — Mirrored the corrected permission recovery instructions.
  • .docs-quality/claims/apple-ads.json — Updated 23 claims (3 new), with 45 evidence windows baselined for changed/new statements.
  • .docs-quality/evals/apple-ads.json — Updated four existing questions and added eight questions for the changed behavior.
  • .docs-quality/evals/apple-ads.holdout.json — Independent coordinator clarified one existing expired/revoked expectation; other entries untouched.
  • .docs-quality/tests/apple-ads-sync.test.mjs — Added eight public contract regression tests with no new dependencies.
  • .github/workflows/docs-quality.yml — Runs the new regression suite in the claims CI job.
  • .claude/state/TASK_JOURNAL.md — Recorded scope, pinned sources, verification, and blocked eval prerequisite.
  • .docs-quality/results/apple-ads/history.jsonl — Recorded failed dev preflight and full holdout execution.
  • .docs-quality/results/apple-ads/2026-10-22T23-35-04-local-dev-doc1-backend-preflight.json — Preserved the dev backend authentication error.
  • .docs-quality/results/apple-ads/2026-10-22T23-40-47-local-holdout-doc1-holdout.json — Preserved all 40 holdout authentication errors.
  • .docs-quality/results/apple-ads/2026-10-23-doc1-validation.md — This reviewable validation report.

Claims touched

  • apple-ads.attribution.media-source-labels-asa-report
  • apple-ads.attribution.media-source-labels-generic
  • apple-ads.connection.connect-button-labels
  • apple-ads.connection.disconnect-result-state
  • apple-ads.connection.status-reconnect-required-expired
  • apple-ads.freshness.budget-usage-far-below-version
  • apple-ads.freshness.budget-usage-what-to-check
  • apple-ads.freshness.import-review-first
  • apple-ads.manage.after-change-confirmed-note
  • apple-ads.manage.after-change-failed
  • apple-ads.manage.after-change-pending
  • apple-ads.manage.apple-permission-check-stale
  • apple-ads.manage.bid-keywords-only
  • apple-ads.manage.pause-resume-all-levels
  • apple-ads.manage.rate-limit-daily-increases
  • apple-ads.manage.ui-not-delivering-word
  • apple-ads.manage.ui-status-switch
  • apple-ads.mcp-api.write-permission-data-stale
  • apple-ads.mcp-api.write-validation-422
  • apple-ads.manage.through-mcp-every-live-bid-or
  • apple-ads.connection.public-disconnect-compatibility
  • apple-ads.mcp-api.write-error-envelope
  • apple-ads.mcp-api.write-body-too-large-json

Fails before / passes after

The exact new suite was copied into a temporary extraction of the eight relevant origin/main source files using git archive; the shared checkout and implementation worktree were not reverted. Command on each tree:
Before (origin/main):
After:
The tests cover the V4 envelope required fields, JSON 413 on both idempotency paths, stored-source/display-label mapping, explicit-disconnect/public compatibility, far-below advice, menu controls, OAuth/legacy stale-permission recovery, and added-row import dates/currencies.

Full offline suite and lint

All commands exit 0:
Relevant result tails:
The link validator’s warnings are its unchanged grandfathered baseline. Redocly was also run on the original spec to establish no warning growth. Python’s openapi-spec-validator could not be installed using a venv because this VM lacks ensurepip/pip; the spec was instead checked by Redocly, swagger-cli OpenAPI validation, and PyYAML with the CI malformed-response-object check. No host packages were installed.

Eval execution and limitation

The requested holdout command was run:
Result: 40 questions, 40 infrastructure errors; zero graded answers. Backend:
The one-question dev preflight had the same authentication error. No ANTHROPIC_API_KEY is present on the VM. The runner records zero-valued metrics when all calls error; those are not meaningful quality scores and the VM run did not pass. The dev repeat-3 run and model-based ledger/page audits remain unverified until the external VM Claude CLI session is renewed or a configured Anthropic API key is supplied. No reauthentication was attempted.

Later Mac holdout (separate run)

The later doc1-holdout-mac run used the same holdout bank: 40 graded answers, 0 errors, pass_rate 0.975 (39/40), fact_recall 1. The single failed question was h.mcp-api.bid-currency-422. Its recorded docs_sha is 7c07e96; it was not run against the final reviewed head. This is distinct from the VM’s doc1-holdout authentication failures and does not replace that infrastructure record. Evidence: 2026-10-22T23-51-52-local-holdout-doc1-holdout-mac.json and its entry in history.jsonl. No eval was rerun on the VM for DOC1b because its credential remains expired. A fresh run against the final reviewed head remains outstanding.

Risks, release and compatibility

  • Documentation-only change: no flag changes, migrations, runtime writes, deployments, PRs, or production queries.
  • Existing pages, slugs, stored media-source values and public connection enums stay compatible; old renamed-heading anchors are explicitly retained.
  • v6 is recorded in internal evidence; published budget advice retains the lifecycle/budget-history qualifications already on the page.
  • Next-release reload-persistent confirmed changes (30 minutes) and corresponding bulk behavior were deliberately excluded. The docs-feature workflow permits pre-release assertions only if they stay true without the new code.
  • The brief’s broad specific-code preservation claim is not true for the gateway’s 5xx path: it still replaces upstream 5xx with storage_error (or its own network_error on timeout). The docs preserve this behavior and promise explicit-code retention only for 4xx. The backend normalizer preserves kill_switch, but it is not end-to-end over REST.
  • No live API or production verification was performed, per task scope. Text-only changes use CI/build checks rather than dashboard screenshots.

Reviewer questions

  1. Is the gateway’s generic 5xx behavior intentional, or should preserving kill_switch end-to-end be a separate runtime fix?
  2. Who can renew the VM eval credential or run evaluation on the Mac so the holdout and dev repeat-3 evaluation can be verified against the final reviewed head before merge?

DOC1b — review follow-up verification (2026-10-23)

Pulled sam/dev-2080-docs-sync to f055d5e in its existing worktree. Rechecked fetched origin/main at dash-mono 05417021b31c906874451a0ac39559b7e98dd810 and api-gateway 7dfd82a2e6f4cbf02f39139d5216c06461cfa07f without modifying either checkout.

Source findings and focused changes

  • Campaign status actions: AppleAdsWriteRequest::normalizeStatus uses ENABLED/ACTIVE and PAUSED; WriteAwareCells.tsx labels the action Enable/Pause. Overview/report prose, matching claims and eval facts now use enable. Existing claim IDs, old heading anchors, the RESUME API alias, reconnect wording and verbatim UI copy remain compatible.
  • error.class: AppleAdsWriteError::project normalizes only type, code and message, retaining class metadata. AppleAdsGatewayWriteErrorTest::testWriteOutcomesAddV4FieldsAndPreserveExistingData explicitly checks arrays, objects, numbers, booleans and null are preserved. Gateway appleAdsWriteV4Error likewise retains json.RawMessage class values unchanged, using a string only for fallback-code selection. A type: string constraint would misrepresent the public body. The optional class schema remains unconstrained and now documents its normal string form and handling of non-string values.
  • 422: AppleAdsWriteService::validationError provides error.fields; its later refusal path forwards the supplied error body without adding fields. The REST and MCP rows and matching claim now express the same conditional fields contract as the OpenAPI response description.
  • Mac evaluation: the separate historical run and its reviewed-head limitation are recorded above and in the journal; saved evaluation artifacts were not edited. No eval was run for DOC1b.

Regression evidence

Added four cases to .docs-quality/tests/apple-ads-sync.test.mjs: consistent enable terminology across pages/ledger/banks; separate Mac provenance and metrics in report/journal; optional unconstrained class metadata; and conditional 422 fields in REST/MCP documentation. The new cases were run against the pulled f055d5e content before making the fixes, then against the fixed files:

Full follow-up checks

CodeRabbit CLI review was attempted once with coderabbit review --light --agent --uncommitted; it stopped with environment_unsupported because agent login requires a localhost browser callback. No reauthentication was attempted; the focused diff was reviewed locally. Python openapi-spec-validator remains unavailable; swagger-cli and Redocly supplied OpenAPI validation. Documentation only: no flags, migrations or deploy order; revert the docs commit to roll back. No production queries, runtime writes, PR changes or other-repository edits. Evaluation on the final reviewed head remains outstanding, and the Mac run’s single failed question remains historical evidence rather than a claimed pass. The class constraint suggestion is intentionally declined based on the pass-through behavior above. Reviewer follow-up: arrange final-head evaluation when credentials are available; no further implementation question for these four threads.