Skip to content

Documentation Site

The Rewards Assistant platform spans six repos (consumer-agent, consumer-context-service, consumer-graph-worker, rover-agent, rover-mcp, consumer-graph-mcp) plus the Platform Spec Lab Confluence page, plus per-repo READMEs, plus PR descriptions for design decisions. A vertical team (Play, eReceipts, Restaurant Network) onboarding to the platform today has to know which repo a piece of documentation lives in to find it — there is no single hosted surface that aggregates the platform’s documentation.

The ticket originally framed this as “build a documentation site (e.g., MkDocs / Docusaurus / similar) hosted under a Fetch-managed URL.” Research surfaced that this site already exists: tech-docs.fetchrewards.com is Fetch’s centralized engineering documentation portal, built on Docusaurus, hosted via the FSD-managed fetch-docusaurus-v3 service. It has:

  • Okta SSO via load balancer
  • Async rebuild from S3-uploaded Markdown via an SQS queue and ECS builder
  • Search (Typesense)
  • A reusable GitHub Actions workflow (fetch-rewards/common-workflows/docusaurus) any repo can plug into in one PR
  • Existing sections: frontend, backend, data, android, devtools, tutorial — a fixed, engineering-discipline taxonomy, hard-allowlisted in the reusable workflow and in fetch-docusaurus-v3 (navbar + sidebars + pipe/startup.sh). Adding a section is a code PR against fetch-docusaurus-v3, owned by the Tech Docs team; it has only ever been done for platform-wide disciplines (Data, Dev Tools), never for a single project, and there is no formalized self-serve request process.
  • A documented contribution model (Markdown in docs/, workflow invocation, optional swagger.yaml for OpenAPI publishing). Each repo publishes to s3://.../{section}/{repo_slug}/, so a repo_slug carrying a slash (rewards-assistant/consumer-agent) nests the repo inside a shared folder under a section.

None of the six Rewards Assistant repos publish to tech-docs.fetchrewards.com today. Per-repo docs/ directories are populated (consumer-agent has 16 files including architecture/dev/deployment guides; CGW has 13 files including graph-schema, runbooks, repurchase-nudge-dm; rover-mcp has integration guides like APPS_SDK_INTEGRATION and WIDGET_BUTTON_PATTERN), but none of that content is hosted, searchable, or discoverable through the platform’s central docs portal.

PF-7 closes the gap by wiring the Rewards Assistant repos into the existing tech-docs platform, not by building a new one. Three load-bearing commitments:

  1. Use the existing tech-docs.fetchrewards.com. No new docs site, no new infra. The Tech Docs team (#proj-tech-docs, DevOps) owns the platform; PF-7 is a consumer of it.
  2. A shared rewards-assistant/ folder under the backend section groups the platform’s six repos for discoverability — achieved via repo_slug: rewards-assistant/<repo>, not a new top-level section (which the platform doesn’t support per-project — see above). A vertical team browsing to tech-docs.fetchrewards.com/backend/rewards-assistant/ sees the platform’s repos grouped together rather than scattered across backend’s alphabetical list. This requires zero Tech Docs dependency: no allowlist change, no section request. The tradeoff is that the top-level navbar still reads “Backend” rather than “Rewards Assistant” — a true navbar label would need a Tech Docs PR and is deferred (§6, §8.2); the folder grouping and shared URL prefix are sufficient for v1.
  3. Platform specs live at docs/specs/<id>.md in their owning repo. The Platform Spec Lab Confluence page remains the authoritative roster; the docs site is the hosted, searchable home for the markdown content.
  • Shared folder under backend. No section request. The six repos publish under a shared rewards-assistant/ folder inside the existing backend section by setting repo_slug: rewards-assistant/<repo> in each repo’s docs.yml. The folder grouping needs no coordination with the Tech Docs team — it works on the existing platform as-is. (A true top-level navbar label would need a Tech Docs PR; it is deferred — see §6, §8.2.)
  • Per-repo wiring. Each of the six repos gets:
    1. A docs/index.md landing page (or a README.md fallback per the docusaurus workflow’s behavior).
    2. A new .github/workflows/docs.yml invoking the reusable docusaurus workflow from fetch-rewards/common-workflows, configured with section: backend and repo_slug: rewards-assistant/<repo>.
    3. A move of any existing specs/*.md to docs/specs/*.md (preserving content, only relocating; existing PRs in flight that touch specs/ need coordination — see §7).
    4. A swagger.yaml artifact if the repo exposes an API (consumer-agent and consumer-context-service in particular).
  • Cross-repo landing index. A single Markdown page listing every platform spec with a link to its hosted location. Lives at consumer-agent/docs/platform-index.md (NOT consumer-agent/docs/index.md — that path is reserved for consumer-agent’s own landing page per §4.5). The cross-repo index is reachable at tech-docs.fetchrewards.com/backend/rewards-assistant/consumer-agent/platform-index and is the page consumer-agent’s own docs/index.md links to as the platform-wide TOC.
  • Convention spec for what publishes where. §4 below codifies which content type lives where: per-repo docs (<repo>/docs/), platform specs (<owning-repo>/docs/specs/), cross-cutting guides (consumer-agent’s docs/ since it’s the central repo), API references (auto-generated from swagger.yaml per the docusaurus workflow’s built-in hook).
  • Cross-repo link discipline. Convention that links between specs in different repos MUST use absolute tech-docs URLs. The docusaurus workflow does not natively resolve cross-repo links.
  • Markdown syntax validation as a merge gate. The reusable workflow validates syntax automatically; PF-7 declares that PRs touching docs/ must pass this validation before merge.
  • Building a new docs site or replacing tech-docs.fetchrewards.com. The existing platform is the answer; PF-7 doesn’t compete with it.
  • Owning the tech-docs platform. The Tech Docs team (#proj-tech-docs, DevOps) owns the Docusaurus build, the FSD service, the EFS-backed NGINX serving, the SSO config, the Typesense search instance. PF-7 is a consumer; bug reports, feature requests, and infrastructure changes go to that team.
  • Customer-facing docs. Per the ticket — out of scope.
  • Marketing site / public roadmap. Per the ticket — out of scope.
  • Per-vertical product docs. Those belong with each vertical’s repo or with the Verticals Spec Lab once it splits out from the Q2 Spec Creation Lab.
  • Versioning per-release snapshots. The Jira ticket mentions versioned docs as an in-scope item, but the existing tech-docs platform doesn’t natively support per-release snapshots today. v1 of PF-7 ships without it; coordinate with the Tech Docs team if it becomes a real requirement (§8 open question).
  • Content authoring. PF-7 sets conventions for what publishes where; it does not write the platform’s documentation content. Per-spec content is owned by the spec author.
  • Replacing the Platform Spec Lab Confluence page. Confluence remains the authoritative roster — the dependency graph, the decisions table, the status column. The docs site is the hosted home for the markdown body of each spec, not a replacement for the roster.

Section assignments live in the Platform Spec Lab, not in this spec. The general convention as of 2026-05-29 is: PC-* (Chat Stack) → consumer-agent; PD-* (DM Stack) → consumer-graph-worker; PS-* (Services) → consumer-context-service; PF-* (Foundation) → consumer-agent. Specs sometimes split across repos (e.g., PS-1 references both CCS and CGW); the lab page is the source of truth, and when in doubt the spec’s own id: frontmatter says where it lives. The table below is a snapshot for reviewer convenience as of 2026-05-29; it is not normative — drift from the lab page is expected over time, and the prose at §1 + §2.1 (one YAML file per repo, specs at docs/specs/<id>.md) is the load-bearing convention.

Snapshot as of 2026-05-29:

RepoTech-docs URLWhat lives in docs/What moves from specs/ to docs/specs/
consumer-agenttech-docs.fetchrewards.com/backend/rewards-assistant/consumer-agent/Architecture, dev guide, deployment, MCP, Opik, integration testing, GSI deployment, experiments (existing content); the platform-index landing pageproduct-search-consolidation.md (existing); PC-* specs, PF-1 / PF-4 / PF-5 / PF-7 (this spec) / PF-8 once they land
consumer-context-servicetech-docs.fetchrewards.com/backend/rewards-assistant/consumer-context-service/Enrichment-persistence-pipeline, local-testing-notes, RFDs (existing)PS-1 / PS-2 / PS-3 / PS-4 / PS-6 once they land (PS-1 has dual residence with CGW per the lab)
consumer-graph-workertech-docs.fetchrewards.com/backend/rewards-assistant/consumer-graph-worker/Architecture/, runbooks/, graph-schema, repurchase-nudge-dm, neo4j-* (existing content)repurchase-candidate-selection.md (existing); PD-1 / PD-2 / PD-3 (already specs in flight via PRs #179/#180/#181); PS-1’s CGW-side content if the lab keeps the dual-residence
rover-agenttech-docs.fetchrewards.com/backend/rewards-assistant/rover-agent/api/, streaming/, system-prompt-guide; the existing README_DOCKER.md, METRICS.md, grafana.md move into docs/(none today)
rover-mcptech-docs.fetchrewards.com/backend/rewards-assistant/rover-mcp/APPS_SDK_INTEGRATION, METRICS, TESTING_WIDGETS, WIDGET_BUTTON_PATTERN, agents/ (existing); OAUTH_* moves from root into docs/(none today)
consumer-graph-mcptech-docs.fetchrewards.com/backend/rewards-assistant/consumer-graph-mcp/QUICKSTART, SCHEMA, REWARDS_SCHEMA_DESIGN, DEMO_USERS, SEEDING (move from root into docs/); agents/(none today)

PS-5 (trace + event store) is not in the snapshot because it’s still being authored — when it lands the lab will name its owning repo; PF-7 doesn’t pre-commit a destination.

Content not moved. Repo-root files that are operationally important to keep at the root stay there: README.md (workflow uses it as fallback if docs/index.md is missing, but README is also the GitHub-rendered landing), SECURITY.md (GitHub recognizes by convention), CLAUDE.md (Claude Code consumes by convention), TODO.md (working notes). These are NOT moved into docs/.

Every repo’s docs/ directory contains content scoped to that repo: how to set it up locally, how to deploy it, its operational runbooks, its architecture, its API reference. The docusaurus workflow renders the directory as a section page at tech-docs.fetchrewards.com/backend/rewards-assistant/<repo>/.

Platform specs (PC-, PD-, PS-, PF-) live at docs/specs/<id>.md in the repo that owns the section (per the Spec Lab section assignments):

  • PC-* specs → consumer-agent/docs/specs/PC-N.md
  • PD-* specs → consumer-graph-worker/docs/specs/PD-N.md
  • PS-* specs → consumer-context-service/docs/specs/PS-N.md
  • PF-* specs → consumer-agent/docs/specs/PF-N.md (Foundation specs live with the central platform repo)

Existing PR-stage specs at consumer-graph-worker/specs/PD-{1,2,3}.md move to docs/specs/PD-{1,2,3}.md as part of PF-7 Phase 1.

Onboarding walkthroughs, “how to add a new BFF enricher,” “how to register a DM type via PD-3,” and similar cross-cutting content live in consumer-agent/docs/guides/. A vertical team starts at tech-docs.fetchrewards.com/backend/rewards-assistant/consumer-agent/guides/ for the platform onboarding journey.

Why consumer-agent hosts the cross-cutting guides:

  • It owns the most spec sections. Per §3, consumer-agent hosts both PC-* (Chat Stack) and PF-* (Foundation) specs — 11+ specs in total across the platform’s roster. CGW hosts PD-* (3 specs); CCS hosts PS-* (6 specs). A vertical team browsing for “how the platform works” finds the most platform-spec breadth in consumer-agent.
  • It hosts the cross-repo landing index (§4.5 — consumer-agent/docs/platform-index.md). The platform-wide table of contents already lives in this repo. Cross-cutting guides sit naturally alongside the index.
  • Consumer-agent is the platform’s user-facing surface. A vertical team integrating with the Rewards Assistant interacts with consumer-agent’s orchestrator, sub-agent composition, mobile streaming, and prompt CI/CD — that’s the largest part of the platform’s user-facing surface area. Onboarding guides are downstream of the orchestrator’s API.

If a guide is genuinely scoped to a single repo’s concerns (e.g., “how to add a new Cypher query to CGW”), it belongs in that repo’s docs/ directory, not in consumer-agent/docs/guides/. The cross-cutting guides directory is for guides that span at least two repos or that introduce the platform as a whole.

Drift discipline. A guide that references a specific spec (“How to register a DM type via PD-3”) becomes stale when that spec changes. To prevent silent drift:

  • Each guide’s frontmatter MUST list references: — an array of spec ids the guide draws content from (e.g., references: [PD-3-type-registry, PS-6-domain-object-enrichment]).
  • Each guide’s frontmatter MUST list owners: — the engineers responsible for keeping the guide in sync (typically the original author plus the author of any referenced spec).
  • When a referenced spec changes substantively (anything beyond editorial), the spec author opens a follow-up PR updating the affected guide(s). The platform-index drift lint (§7.6) doesn’t catch this — it’s a process-level discipline, not a mechanical one.

A v2 enhancement could lint that every guide’s references: list points at extant spec ids; out of scope for v1.

v1 OpenAPI publishing scope: two repos. Only consumer-agent and consumer-context-service publish OpenAPI references via the workflow’s swagger.yaml hook. Both are FastAPI services with real customer-facing HTTP APIs that benefit from a hosted reference. The other four repos are excluded by intent:

  • consumer-graph-worker — Go service with VPN-only internal endpoints (per its CLAUDE.md). Not consumer-facing; OpenAPI publishing adds no value.
  • rover-agent, rover-mcp, consumer-graph-mcp — MCP servers using the MCP protocol (not REST), with their own tool-schema documentation (see the mcp-tool-schemas skill for the discovery pattern). A REST-style OpenAPI publish would be misleading.

For consumer-agent + CCS, swagger.yaml is generated by running FastAPI.openapi() in a CI job (canonical script: scripts/export_openapi.py per repo), uploaded as a CI artifact, and downloaded by the docs workflow via its download-swagger: true option.

Behavior on malformed OpenAPI spec. If the uploaded swagger.yaml is malformed, the docusaurus workflow logs the failure and continues publishing the rest of the repo’s docs. The OpenAPI page itself doesn’t render, but the rest of the section stays available. PRs that introduce a malformed swagger.yaml should be caught by a CI step that validates the export before upload — that’s the repo’s job, not the docs workflow’s.

If a future MCP repo or CGW endpoint surface genuinely needs hosted API reference docs (unlikely in v1), the OpenAPI scope grows additively — adding a repo to the list is a PF-7 update PR, not a structural change.

A single Markdown page provides the platform-wide table of contents. Lives at consumer-agent/docs/platform-index.md — a sibling of consumer-agent/docs/index.md, NOT the same file.

The two pages have different jobs:

  • consumer-agent/docs/index.md — consumer-agent’s own landing page (architecture, dev guide, deployment, the things that scope to this repo). Reached at tech-docs.fetchrewards.com/backend/rewards-assistant/consumer-agent/.
  • consumer-agent/docs/platform-index.md — the platform-wide TOC across all six repos. Reached at tech-docs.fetchrewards.com/backend/rewards-assistant/consumer-agent/platform-index. Linked prominently from consumer-agent/docs/index.md.

The platform-index.md has the following structure:

# Rewards Assistant Platform Documentation
## Platform Specs
### Chat Stack
- [PC-1 — Sub-Agent Composition](https://tech-docs.fetchrewards.com/backend/rewards-assistant/consumer-agent/specs/PC-1)
- [PC-2 — Runtime Sub-Agent Dispatch](https://tech-docs.fetchrewards.com/backend/rewards-assistant/consumer-agent/specs/PC-2)
- (...)
### DM Stack
- [PD-1 — Scheduled DM Execution](https://tech-docs.fetchrewards.com/backend/rewards-assistant/consumer-graph-worker/specs/PD-1)
- [PD-2 — DM Delivery & notification-service Contract](https://tech-docs.fetchrewards.com/backend/rewards-assistant/consumer-graph-worker/specs/PD-2)
- [PD-3 — DM Type Registry & Rollout](https://tech-docs.fetchrewards.com/backend/rewards-assistant/consumer-graph-worker/specs/PD-3)
### Services
- [PS-1 — Knowledge Graph Service](https://tech-docs.fetchrewards.com/backend/rewards-assistant/consumer-context-service/specs/PS-1)
- (...)
### Foundation
- [PF-1 — Sub-Agent Lifecycle](https://tech-docs.fetchrewards.com/backend/rewards-assistant/consumer-agent/specs/PF-1)
- (...)
- [PF-7 — Documentation Site](https://tech-docs.fetchrewards.com/backend/rewards-assistant/consumer-agent/specs/PF-7)
- (...)
## Per-Repo Documentation
- [consumer-agent](https://tech-docs.fetchrewards.com/backend/rewards-assistant/consumer-agent/) — Orchestrator, sub-agent host, mobile streaming
- [consumer-context-service](https://tech-docs.fetchrewards.com/backend/rewards-assistant/consumer-context-service/) — Domain enrichment, BFF assembly
- (...)
## Authoritative Roster
See the [Platform Spec Lab](https://fetchrewards.atlassian.net/wiki/spaces/Pilot/pages/6452412451)
on Confluence for the complete spec roster, dependency graph, status, and decisions.
This site is the hosted home for the markdown body of each spec.

Maintenance ownership. The index is hand-maintained per spec landing. When a new spec lands in any of the six repos, the author of the new spec opens a one-line follow-up PR against consumer-agent/docs/platform-index.md adding the entry. v2 enhancement: a generator script that reads each repo’s docs/specs/*.md frontmatter and rebuilds the index automatically; would live in consumer-agent/scripts/ alongside the cross-repo link lint. Out of scope for v1; a stale link or two on the index is a survivable failure mode.

Markdown links between specs that live in different repos MUST use absolute tech-docs.fetchrewards.com URLs. The docusaurus workflow’s per-repo build does not resolve relative cross-repo paths (each repo’s docs render in its own subtree of the unified build; relative links would have to traverse ../../<other-repo>/specs/, which doesn’t work cleanly).

For example, PD-1 (in consumer-graph-worker) linking to PS-6 (in consumer-context-service) must use:

See [PS-6 §4.2](https://tech-docs.fetchrewards.com/backend/rewards-assistant/consumer-context-service/specs/PS-6#section-4-2)

NOT:

See [PS-6 §4.2](../../consumer-context-service/specs/PS-6.md#section-4-2)

In-repo links (PD-1 linking to PD-2, both in consumer-graph-worker) use relative paths normally:

See [PD-2 §4.5](./PD-2.md#section-4-5)

Each repo’s .github/workflows/docs.yml invokes the reusable workflow from fetch-rewards/common-workflows. Example for consumer-graph-worker:

name: Publish docs to tech-docs.fetchrewards.com
on:
push:
branches: [main]
paths: ['docs/**', 'swagger.yaml', 'README.md']
pull_request:
paths: ['docs/**', 'swagger.yaml', 'README.md']
jobs:
validate-on-pr:
if: github.event_name == 'pull_request'
uses: fetch-rewards/common-workflows/.github/workflows/docusaurus.yml@main
with:
section: backend
repo_slug: rewards-assistant/consumer-graph-worker
environment: dev
validate_only: true
secrets: inherit
publish-on-main:
if: github.event_name == 'push' && github.ref == 'refs/heads/main'
uses: fetch-rewards/common-workflows/.github/workflows/docusaurus.yml@main
with:
section: backend
repo_slug: rewards-assistant/consumer-graph-worker
environment: prod
validate_only: false
secrets: inherit

(API-exposing repos — consumer-agent, CCS — add an export-openapi job that uploads a swagger.yaml artifact, and set download-swagger: true on the calls above; see §4.4 and the consumer-agent docs.yml as the reference implementation.)

validate_only: true on PR runs the Markdown syntax validation as a merge gate without uploading; the same job runs on push to main with validate_only: false to upload the validated docs. The secrets: inherit carries the DOCUSAURUS_PAT and OIDC credentials the workflow needs — DOCUSAURUS_PAT is configured at the org level by the Tech Docs team, so individual repos don’t need to manage it.

section: backend + repo_slug: rewards-assistant/<repo> — this is the load-bearing choice and it deliberately does not request a new section. The reusable workflow validates section against a hard allowlist (frontend, backend, data, android, devtools, tutorial) baked into fetch-docusaurus-v3 (navbar + sidebars + pipe/startup.sh); rewards-assistant is not in it and there is no self-serve way to add it. Rather than gate the entire rollout on an unprecedented, process-less Tech Docs ask, we exploit the fact that the workflow interpolates repo_slug straight into the S3 sync point (s3://{env}-fetch-docusaurus-v3-builder/{section}/{repo_slug}/): a slash in repo_slug nests the repo inside a shared rewards-assistant/ folder under backend. All six repos use repo_slug: rewards-assistant/<their-repo>, landing at tech-docs.fetchrewards.com/backend/rewards-assistant/<repo>/.

--delete safety: each repo’s aws s3 sync --delete ./docs $SYNC_POINT is scoped to its own rewards-assistant/<repo>/ prefix, so the six repos cannot delete each other’s content.

The one thing this approach does not give us is a top-level navbar entry reading “Rewards Assistant” — the navbar still shows “Backend,” with the platform’s repos grouped beneath a rewards-assistant folder in that section’s sidebar. A real navbar label would require a Tech Docs PR against fetch-docusaurus-v3; it is deferred and explicitly not a dealbreaker for v1 (§6, §8.2). The folder grouping + shared URL prefix + platform-index.md deliver the “one platform” discoverability goal without it.

PF-7 introduces a few coordination touchpoints with the Tech Docs team (#proj-tech-docs):

  1. None required to ship v1. The shared-folder approach (§5) needs nothing from the Tech Docs team — no section, no allowlist change, no config PR. This is the whole point of choosing repo_slug nesting over a section request: the rollout has zero hard dependency on Tech Docs. The touchpoints below are all optional, deferred, or passive.
  2. Top-level navbar label (deferred, optional). If the platform later wants the navbar to read “Rewards Assistant” as its own entry (rather than living under “Backend”), that requires a Tech Docs PR against fetch-docusaurus-v3 (navbar config + sidebars + the pipe/startup.sh allowlist) — the same code change a true new section needs. Deferred to v2 and explicitly not a dealbreaker; the folder grouping is sufficient for v1. If pursued, it’s a normal feature request to #proj-tech-docs, not a blocker.
  3. Versioned per-release snapshots (deferred, v2+). If versioning becomes a requirement, the Tech Docs team is the owner of the platform-level capability.
  4. Search tuning (passive). If Typesense indexing misses or misranks platform content, file a request with the Tech Docs team.
  5. Bug reports about the platform. Build failures, broken search, SSO issues — all go to the Tech Docs team, not to PF-7’s owner.
  6. Folder rename or migration. If the shared rewards-assistant/ folder ever needs to be renamed or promoted into a real section, coordinate with the Tech Docs team on redirect setup so existing URLs don’t 404. Forward-looking; not anticipated in v1.

The Tech Docs team uses #proj-tech-docs as their inbound channel and DO-3576 as their epic. The relationship is: PF-7 is one of many consumers of the platform; the Tech Docs team’s roadmap is independent of PF-7’s; PF-7 commits to using the platform as-is and works with the team on platform-level changes only when genuinely needed.

7.1 Phase 0 — (removed) No section provisioning needed

Section titled “7.1 Phase 0 — (removed) No section provisioning needed”

The original Phase 0 was a hard gate on the Tech Docs team provisioning a new rewards-assistant section. That gate is gone (resolved 2026-06-02, PLT-780): per §5, the platform publishes under the existing backend section via repo_slug: rewards-assistant/<repo>, which requires no section, no allowlist change, and no Tech Docs coordination. The rollout starts directly at Phase 1; the first repo to publish creates the backend/rewards-assistant/ folder implicitly via its first S3 sync.

The only remaining pre-work is the cross-repo link lint (§7.1.5), which is independent of any Tech Docs dependency.

A small validation script + reusable workflow that catches cross-repo relative-path links the docusaurus workflow won’t resolve. Two artifacts ship together:

  1. fetch-rewards/common-workflows/scripts/lint_cross_repo_links.py (~50 lines) — the script itself. Home: common-workflows (NOT consumer-agent). Rationale: the lint runs from every Rewards Assistant repo’s .github/workflows/docs.yml, so the natural home is the same repo as the reusable docusaurus workflow it composes with. Putting it in consumer-agent would force the other five repos to either reach across repos or duplicate the script.
  2. fetch-rewards/common-workflows/.github/workflows/lint-cross-repo-docs-links.yml — the reusable workflow wrapper. Other repos invoke it via uses: fetch-rewards/common-workflows/.github/workflows/lint-cross-repo-docs-links.yml@main alongside the existing docusaurus.yml workflow.

Lint contract:

  • Input: a list of docs/specs/*.md files (or a docs/ directory to recurse).
  • Pass: all Markdown links are either (a) intra-doc anchors (#section-X), (b) intra-repo relative paths (./PD-2.md, ../guides/onboarding.md), or (c) absolute URLs (https://...).
  • Fail: any link of the form ../../<other-repo-name>/... where <other-repo-name> matches one of the six known Rewards Assistant repos.
  • Exit code 0 / 1 for CI gating.

The other five repos’ docs.yml workflows reference the lint workflow with a single uses: line — no “we’ll figure this out” pivot needed when Phase 1+ ships. Land the lint PR against common-workflows before or alongside Phase 1; with Phase 0 removed it is the only remaining pre-work, and it has no Tech Docs dependency.

7.2 Phase 1 — consumer-graph-worker (proving ground)

Section titled “7.2 Phase 1 — consumer-graph-worker (proving ground)”

Sequencing constraint: PD-1, PD-2, PD-3 are in flight as separate PRs (#179, #180, #181) that currently write to specs/PD-N.md. PF-7 Phase 1 lands after those three PRs merge, in a single follow-up PR that moves all specs/*.md files in CGW to docs/specs/*.md at once. Rationale: rebasing three in-flight spec PRs onto a different file path during their review cycle is more disruptive than a one-shot move PR after they land. The DM Stack spec PRs have review feedback applied and are nearing merge; the rename is mechanically trivial after they merge.

Fallback timeline. If PD-1/PD-2 take longer than expected (>30 days from PF-7 merge), the rollout pivots: run Phase 2 (consumer-agent) first instead of waiting on CGW. consumer-agent’s existing spec set (product-search-consolidation + PF-7 itself + any landed Foundation specs) is enough to demonstrate the platform-index page works end-to-end. CGW catches up when the DM-Stack PRs land. The pivot is conservative: no platform spec content is held hostage to CGW’s review pace, and the proving-ground value of “verify the workflow + the shared folder work on real content” is preserved by running it on consumer-agent’s specs. (As of PLT-780, Phase 2 has in fact shipped first — consumer-agent is the proving ground.)

  1. Wait for PR #179 (PD-3), PR #180 (PD-1), PR #181 (PD-2) to merge on consumer-graph-worker’s main branch.
  2. Land a follow-up CGW PR that:
    • Renames specs/PD-1.md, specs/PD-2.md, specs/PD-3.md, specs/repurchase-candidate-selection.mddocs/specs/PD-1.md, docs/specs/PD-2.md, docs/specs/PD-3.md, docs/specs/repurchase-candidate-selection.md. Use git mv so file history is preserved.
    • Sweep cross-repo Markdown links in the moved specs. During the rename PR, audit links in the four moved specs for any cross-repo relative paths (e.g., PD-3 referencing PF-8 via ../../consumer-agent/...) and rewrite to absolute tech-docs URLs (per §4.6). The cross-repo link lint (§7.1.5) catches new violations going forward, but the move itself is the right opportunity to clean up existing relative links if any.
    • Adds docs/index.md (CGW landing page within the shared folder).
    • Adds .github/workflows/docs.yml invoking the reusable workflow with section: backend and repo_slug: rewards-assistant/consumer-graph-worker.
  3. After merge, verify CGW content is reachable at tech-docs.fetchrewards.com/backend/rewards-assistant/consumer-graph-worker/.

Phase 1 is the proving ground — if anything’s wrong with the workflow, the shared-folder grouping, or the move, we catch it on one repo before fanning out.

7.3 Phase 2 — consumer-agent (Foundation specs + cross-repo index + first onboarding guide)

Section titled “7.3 Phase 2 — consumer-agent (Foundation specs + cross-repo index + first onboarding guide)”
  1. Land a consumer-agent PR that:
    • Adds docs/index.md (consumer-agent’s own landing page).
    • Adds docs/platform-index.md (the cross-repo landing page from §4.5; distinct from index.md per §4.5).
    • Moves the existing specs/*.md (currently just product-search-consolidation; PF-1, PF-4, PF-5, PF-8 may also exist or be in flight) to docs/specs/.
    • Adds docs/guides/onboarding-platform.mdfirst cross-cutting onboarding guide (the high-level “what is the Rewards Assistant platform” walkthrough). Ship the first guide alongside the wiring so the platform-index page links to working content from day one. Additional guides (“How to register a DM type via PD-3”, “How to add a new BFF enricher”) land in follow-up PRs.
    • Adds .github/workflows/docs.yml.
    • Adds scripts/export_openapi.py (canonical FastAPI OpenAPI export script — see §4.4 + §8.5).
    • CI wires the export to upload swagger.yaml as an artifact for the docs workflow’s download-swagger: true step.
  1. Same shape as Phase 2 but for CCS.
  2. Migrate the existing PS-* specs (whichever are landed) into docs/specs/.
  3. Wire OpenAPI publishing.

7.5 Phase 4 — rover-agent, rover-mcp, consumer-graph-mcp

Section titled “7.5 Phase 4 — rover-agent, rover-mcp, consumer-graph-mcp”
  1. Lower priority; these repos have less platform-spec content. Wire the workflow, expose their existing per-repo docs, and call it done.

CI gates (per-PR, all merge-blocking on PRs touching docs/**):

  • Markdown syntax validation via the reusable workflow’s validate_only: true PR run.
  • Cross-repo link disciplineconsumer-agent/scripts/lint_cross_repo_links.py (authored in Phase 0.5; see §7.1.5) scans docs/specs/*.md for cross-repo relative-path links and rejects them. Other repos invoke it via the reusable workflow.
  • Frontmatter completeness for specs — a lint that asserts every docs/specs/*.md has the full spec-creation-skill frontmatter keyset: id, title, section, status, priority, created, updated, author, jira.epic, depends_on, blocks, in_scope, out_of_scope, tech.language, tech.framework, tech.platform. Looser drafts (early WIP) can suppress via a wip: true frontmatter field that exempts the file from the lint — but the lint defaults to strict.
  • Platform-index drift lint (Phase 2+) — when a new docs/specs/*.md lands in any of the six repos, the PR’s CI must verify there’s a matching entry in consumer-agent/docs/platform-index.md. The lint runs against the index file and the union of docs/specs/*.md across all repos (via the reusable workflow); any spec without an index entry fails the build. Pairs with the maintenance-ownership convention in §4.5 — the spec author owns adding the index entry, the lint enforces it.

Production observability gates:

  • Tech-docs site freshness — the Tech Docs team’s documented rebuild SLA is approximately 15 minutes from S3 upload to live site. PF-7 doesn’t enforce this — it’s the platform’s. If a content change isn’t visible within the window, the PR author files a ticket with #proj-tech-docs (named owner — not “the team,” not “someone”; the engineer who merged the doc change is the one who notices and escalates). The Tech Docs team’s epic DO-3576 tracks platform-level fixes.
  1. Versioned per-release snapshots. The Jira ticket lists versioned docs as in-scope. The existing tech-docs platform doesn’t natively support per-release snapshots. Options: (a) defer to v2; (b) coordinate with the Tech Docs team for a platform-level feature; (c) use git tags + the rebuild trigger to snapshot. Recommend (a) — defer until a real use case demands it. PF-4 coordination point: confirm whether any specs need “this was the v1.0 of PD-3” snapshots for legal/compliance audit reasons. If yes, (a) becomes (b) and the platform-version-doc concept gets a real driver. If no (likely, given continuous deploy), (a) holds.
  2. rewards-assistant section name. Resolved 2026-06-02 (PLT-780). No new section is created, so there is no section name to negotiate with the Tech Docs team. The platform publishes under backend/rewards-assistant/rewards-assistant is now just a folder slug we own, chosen to match the platform’s branding (PLT-696 / Platform Spec Lab). The only residual is the deferred navbar-label question (§6.2): if a true top-level “Rewards Assistant” navbar entry is ever pursued, the label/slug convention is the Tech Docs team’s call at that point. Not blocking v1.
  3. Coordination with in-flight specs/ PRs. Resolved 2026-05-26. Phase 1 lands after PD-1/PD-2/PD-3 (PRs #179/#180/#181) merge, then a single follow-up CGW PR moves all specs/*.mddocs/specs/*.md via git mv. See §7.2.
  4. Cross-cutting guide content. §4.3 names consumer-agent/docs/guides/ as the home for cross-cutting onboarding content but doesn’t specify what guides ship in v1. Recommend three initial guides: (a) “Onboarding to the Rewards Assistant platform” (high-level), (b) “How to register a DM type via PD-3” (links to PD-3 + worked example), (c) “How to add a new BFF enricher” (links to PS-6). Lower priority than wiring the workflow; can ship in a follow-up.
  5. OpenAPI export step for FastAPI services. Needs implementation in Phase 2 / Phase 3 — exact CI step shape (where to run app.openapi(), where to upload the artifact, how the docusaurus workflow’s download-swagger: true finds it) needs to be wired with whoever’s authoring Phase 2 + Phase 3.
  6. Cross-repo landing index automation. §4.5’s index is hand-maintained in v1. A generator script that reads each repo’s docs/specs/*.md frontmatter and rebuilds the index automatically is a v2 enhancement. Defer until the index drift becomes operationally annoying.
  7. CLAUDE.md and TODO.md publishing. Should these files publish to the docs site or stay repo-root-only? Recommendation: stay root-only (they’re either Claude-Code-consumed metadata or working notes), not docs content. The workflow filter on paths: ['docs/**', 'swagger.yaml', 'README.md'] excludes them naturally.
  8. Frontmatter reciprocity. PF-7 has no depends_on and no blocks — it’s truly independent per the Jira ticket. No reciprocity check needed.
  • The six repos publish under the shared backend/rewards-assistant/ folder (section: backend, repo_slug: rewards-assistant/<repo>) — no new top-level section requested.
  • Every Rewards Assistant repo has a docs/index.md landing page and a .github/workflows/docs.yml invoking the reusable docusaurus workflow.
  • specs/*.md has been moved to docs/specs/*.md in consumer-agent, consumer-context-service, and consumer-graph-worker (the three repos that own platform specs).
  • The cross-repo landing index page at consumer-agent/docs/platform-index.md (distinct from docs/index.md) lists every platform spec with a working tech-docs URL.
  • OpenAPI references publish for consumer-agent and consumer-context-service via the workflow’s swagger.yaml hook.
  • Markdown syntax validation runs as a merge gate on every PR touching docs/**.
  • A cross-repo link lint runs in CI and rejects relative ../ paths from docs/specs/*.md.
  • After a PR lands on main, the corresponding tech-docs page reflects the change within 15 minutes (the platform’s rebuild SLA).
  • The Platform Spec Lab Confluence page references the backend/rewards-assistant/ folder on tech-docs as the hosted home for spec content (one-line update on the lab page).