---
name: applicaster-continue-watching-favorites
description: "Continue Watching and Favorites: use when adding cross-device Continue Watching or remote favorites to a Zapp Pipes library."
---

# applicaster-continue-watching-favorites

Add a compliant, secure remote Continue Watching and Favorites integration to a new or existing Pipes library. The **contract** is the resolved agreement between Applicaster, the target library, its remote user-state provider, and Zapp. Establish and obtain approval for it before editing.

## Scope

- Use this skill for a new or existing Pipes server that needs cross-device Continue Watching, remote favorites, or both.
- Require a documented remote per-user state provider and an authoritative content hydrator; require favorites operations only when favorites are in scope. Surface either missing prerequisite before implementation.
- Adapt to the target project's language, framework, package manager, configuration, tests, and deployment conventions.
- For receipt-based local endpoint lifecycle validation, use the skill-local [Continue Watching and Favorites E2E tool](tools/continue-watching-favorites-e2e/README.md).

## Non-Negotiable Gates

1. Before proposing an implementation contract or editing files, ask and receive an answer to these two separate questions, one at a time: what marks an item complete, then how a completed item is represented. A provider rule, existing code, or fixture behavior does not replace either developer decision.
2. Do not report the work complete unless the final handoff contains a `## Zapp Configuration` section. This section is mandatory for every implementation, including mock-only work. The optional `zapp-continue-watching-configuration.md` file affects only whether the same procedure is persisted in the target library; it never makes the final handoff optional.
3. In the final report, state the developer's two completion answers and whether the optional configuration guide was created, declined, or skipped because the work is explicitly mock-only.
4. Every Cloud Events route validates its request boundary before dispatch and tests its documented success response. Do not impose one response body or media type across routes; follow the applicable Zapp and target-library contract.

## 1. Establish facts

1. Fetch the current Applicaster Continue Watching, Cloud Events, feed, and relevant Zapp plugin/authentication documentation before reading provider material. Read [applicaster-contract.md](references/applicaster-contract.md) while doing so. Follow only feature-specific documentation needed by the target library.
2. Inspect the target project, its entry mapper, context/token handling, endpoint registration, tests, configuration, and provider API documentation. Search for existing personalization, favorites, resume, event, and content lookup code before proposing new seams.
3. Determine facts without asking: framework, test/build commands, current route conventions, protected endpoint manifest/context-key requirements, token source, user-identity source, content IDs, provider capabilities, and deployment URL shape.
4. Read [patterns.md](references/patterns.md) for portable implementation shapes. Apply an invariant only when the target's documented provider and architecture support it.

Completion: the implementation constraints and existing seams are evidenced by the target code and current provider/docs, not assumptions.

## 2. Resolve developer decisions

Present a concise, sourced fact summary before the first question. Ask only for behavioral or product decisions that facts cannot settle. Ask one question at a time, include the discovered constraint, recommended answer, and a short consequence of choosing differently, then wait for the developer's reply. If a question exposes a missing fact, investigate it and return with an updated recommendation instead of asking the developer to decide under uncertainty. Use [adapter-decision-guidance.md](references/adapter-decision-guidance.md) whenever a provider, identity, ID, hydration, completion, reliability, or configuration decision is unresolved.

Immediately after the fact summary, ask these two questions in dependency order and wait for each answer before continuing. Do not infer either answer from discovered facts:

1. Define what completion means. Recommend the provider's native completion signal, such as `status: COMPLETED`, over a percentage threshold.
2. Define how completed items are represented. Decide whether they are removed or returned with `resumeCompleted: true`; recommend removal when provider behavior does not mandate otherwise.

Resolve these only when facts leave a material ambiguity:

3. Confirm the documented remote state provider can read and write the implemented user state for the same authenticated user, and that the authoritative content hydrator can return complete Pipes entries for saved media IDs.
4. Prefer one stable ID used by Pipes, events, state, and hydration. If IDs differ, agree on explicit event-extension fields and a deterministic mapping.
5. Confirm protected endpoints declare their documented context-key requirements, resolve credentials through the target's context helper, and use the same authenticated principal for event writes and personalized feed reads. Determine whether `data.userIdentifier` is a token or provider identity; when both it and context credentials exist, verify they bind to the same principal. Missing or invalid identity is `401`.
6. Define the progress-event heartbeat. Follow current Applicaster guidance or target conventions; if neither defines it, recommend `30 seconds` for approval.
7. Confirm a safe server-side item cap. Preserve provider newest-first order; add request pagination only when the library already supports it safely. If no cap is established, recommend `50` items per feed for approval.
8. Decide how records that no longer hydrate are handled; recommend omitting unavailable records while preserving valid entries. Provider or hydrator failures remain sanitized `502`/`503` responses, not empty feeds.
9. Confirm native sanitized logging/metrics, provider timeouts, and retry/order behavior. State writes must be idempotent; apply timestamps or provider versions when available. If neither exists, recommend documenting last-received-write-wins for progress writes.

If live protocol documentation cannot be fetched, explain that the bundled snapshot may be stale and ask one question: whether to proceed from it. Do not silently substitute it. If live Zapp configuration documentation cannot be fetched but verified protocol facts permit implementation, continue implementation but mark detailed Zapp configuration and deployed Zapp validation as blocked. Do not invent UI steps or plugin fields.

Completion: every applicable decision has a recorded developer answer, and the unresolved decisions are the only ones presented for confirmation.

## 3. Confirm before edits

Present a concise implementation contract containing:

- The state provider operations and their authentication.
- The entry-ID mapping and content hydration path.
- The Cloud Events `POST`, authenticated Continue Watching `GET`, and authenticated favorites `GET` only when favorites are in scope.
- The supported event types, completion behavior, response/error policy, cap, and affected files.
- The tests, safe smoke test conditions, and Zapp-side checklist.
- The exact CW E2E command when the documented event routes return receipts and its endpoint URLs, event identity, fixture IDs, and any event templates are available; otherwise the specific missing prerequisite.
- Whether to create or update the optional `zapp-continue-watching-configuration.md` beside the target library's README. Create it by default for deployable integrations, allow the developer to decline it, and skip it automatically for explicitly throwaway/mock-only work.

Wait for explicit approval. If a material decision changes later, ask one recommended question and refresh the contract.

Completion: the developer has approved every non-discoverable choice that affects data, auth, routes, or behavior.

## 4. Implement the contract

1. Validate request JSON/body limits, the Cloud Events envelope, supported event type, and event-specific data before calling the state adapter. Accept `video.stopped` and `video.progress`, plus `favorites.added` and `favorites.removed` only when favorites are in scope.
2. Implement and test each route's documented success response. When the route acknowledges an event with a receipt, return `201` plus a Cloud Event containing `specversion`, `type`, `source`, `subject`, `id`, and RFC3339 `time`; otherwise preserve the documented response status, body, and media type. Return safe `400` responses for malformed or unsupported events, `401` for identity failures, and sanitized `502`/`503` responses for state-provider/content-hydrator failures.
3. Build Continue Watching from provider state plus hydrated entries. Include the resume extensions required by the live Applicaster contract on every returned entry. An authenticated user with no state receives a valid empty feed; an upstream failure is not an empty-state response.
4. When favorites are in scope, build favorites from provider state plus the same authoritative hydrator. Preserve the provider's ordering and remove records that no longer hydrate.
5. Update the library's native integration surface: endpoint manifest when present, README/config documentation, deployment descriptors or examples when relevant, and sanitized observability. When approved, create or update `zapp-continue-watching-configuration.md` beside the library README and link it from the README. If no README exists, create only the guide and report that no README link could be added. Make only direct fixes needed for a compliant integration; report unrelated findings separately.

Read [acceptance-matrix.md](references/acceptance-matrix.md) before writing or changing tests.

Completion: every implemented endpoint uses the approved adapter, identity boundary, identifier mapping, and response policy.

## 5. Verify and hand off

1. Run the target project's relevant formatter/typecheck and focused tests during implementation, then its full test suite before completion.
2. Run the acceptance matrix. When favorites are in scope, the documented event routes return receipts, and local endpoint URLs, event identity, fixture IDs, and any required event templates are available, install and run the skill-local CW E2E tool. It validates the live local HTTP boundary without deploying or configuring Zapp. Otherwise run the relevant route tests; if required CW E2E inputs are unavailable, report that command as blocked rather than claiming end-to-end validation.
3. Include a `## Zapp Configuration` heading in the final handoff, followed by the library-specific, step-by-step configuration and validation procedure required by [applicaster-contract.md](references/applicaster-contract.md). Derive it from current relevant `docs.applicaster.com` guides and the implemented library without mutating Zapp. This heading and procedure are required even when the optional Markdown guide was declined or skipped.
4. When the optional guide is approved, keep that same procedure in `zapp-continue-watching-configuration.md`. Update an existing guide rather than creating a second one. Verify that its route values match the implementation, its README link resolves when present, and its cited documentation URLs are reachable. Include the exact local CW E2E command only when it is stable and reproducible from the repository; otherwise retain one-off commands in the final handoff.
5. Report files changed, verification commands/results, required configuration/secrets, the detailed Zapp procedure, CW E2E result or blocker, the two completion decisions, the configuration-guide outcome, and any remaining provider or deployment prerequisite.

Completion: automated checks pass, any skipped live smoke test is identified with its blocker, and the developer has the exact Zapp configuration values to apply.
