> For the complete documentation index, see [llms.txt](https://faction-os.gitbook.io/faction-os-docs/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://faction-os.gitbook.io/faction-os-docs/public-demo/docs_public-demo/deployment.md).

# Deployment

`public-demo/` deploys as a static directory.

## Official Host

Cloudflare Pages is the official host for the public demo.

Current production project:

| Field                    | Value                                                      |
| ------------------------ | ---------------------------------------------------------- |
| Cloudflare Pages project | `factionos-public-demo`                                    |
| Primary domain           | `https://demo.faction-os.com/`                             |
| Pages domain             | `https://factionos-public-demo.pages.dev/`                 |
| Deployment preview shape | `https://<deployment-id>.factionos-public-demo.pages.dev/` |
| Git provider             | Not connected                                              |

Production deploys are direct Wrangler uploads of the `public-demo/` directory. They should be run from a committed local `main` branch and should attach the current commit hash/message to the Pages deployment.

```bash
git status --short public-demo tests/e2e/public-demo.e2e.ts
git push origin main
CLOUDFLARE_ACCOUNT_ID=<account-id> npx wrangler pages deploy public-demo \
  --project-name=factionos-public-demo \
  --branch=main \
  --commit-hash="$(git rev-parse HEAD)" \
  --commit-message="$(git log -1 --pretty=%s)"
```

If Wrangler is already logged in and has a usable account context, the explicit `CLOUDFLARE_ACCOUNT_ID=...` prefix may not be needed. If deploy logs show an API path containing `/accounts//pages/...`, set the account id explicitly or avoid sourcing an `.env` file that defines it as blank.

## Optional Git Integration Shape

If the Cloudflare Pages project is later connected to Git, production deploys can follow the repository's `main` branch. In that model, the Pages project should publish the `public-demo/` directory as the deployed site root.

Recommended Cloudflare Pages settings:

| Setting                | Value                   |
| ---------------------- | ----------------------- |
| Production branch      | `main`                  |
| Root directory         | repository root / blank |
| Build command          | `exit 0`                |
| Build output directory | `public-demo`           |

Do not set both the root directory and build output directory to `public-demo`; that would make Pages look for a nested `public-demo/public-demo` output path. If the root directory is set to `public-demo`, the build output directory should be `.` instead.

The demo has no build step. `exit 0` is only a no-op command that tells Cloudflare Pages the build succeeded before it uploads the static output directory.

## Expected URL Shape

The stable production URL is:

```
https://demo.faction-os.com/
```

The project Pages domain is:

```
https://factionos-public-demo.pages.dev/
```

Direct Wrangler deploys also emit immutable deployment preview URLs such as:

```
https://59629423.factionos-public-demo.pages.dev/
```

Cloudflare Pages serves `public-demo/index.html` at the site root.

## Custom Domains

Custom domains should be managed through the Cloudflare Pages project.

* For an apex domain such as `example.com`, the domain must be added as a Cloudflare zone and use Cloudflare nameservers.
* For a subdomain such as `demo.example.com`, add it in the Pages project's custom domains settings and point DNS at the Pages target.
* HTTPS certificate provisioning is handled by Cloudflare.

The host can attach custom domains for free, but domain registration itself is still handled separately by the domain owner.

## Path Compatibility

The official Cloudflare Pages deployment serves at a domain root, but the demo also supports path-prefixed static hosts because local files use relative URLs:

* `./manifest.webmanifest`
* `./sw.js`
* `./assets/...`
* `./icon-*.png`

The service worker scope is also relative:

```js
navigator.serviceWorker.register("./sw.js", { scope: "./" });
```

This keeps the artifact compatible with fallback URLs such as:

```
https://<owner>.github.io/factionos/
```

## Fallback Static Hosts

If Cloudflare Pages is unavailable, the same directory can be served by other static hosts, including:

* GitHub Pages, if repository Pages is enabled and configured for GitHub Actions
* Netlify
* Vercel static output
* nginx
* Caddy
* S3-compatible static hosting

Use the directory contents as the publish root.

## Required Headers

No custom headers are required for basic operation. The host must serve:

* `.html` as HTML
* `.js` as JavaScript
* `.webmanifest` as a web manifest or JSON-compatible content type
* `.png` and `.jpg` as images

Most static hosts do this automatically.

## First-Load External Dependencies

The first visit must be online and able to reach:

* `https://esm.sh`
* `https://cdn.jsdelivr.net`
* `https://fonts.googleapis.com`
* `https://fonts.gstatic.com`

If those origins are blocked, the first load may render incompletely or fail. After one successful online visit, the service worker can cache allowed CDN responses for offline reloads.

## Deployment Checklist

Before publishing:

1. Commit the public-demo changes and push `main`.
2. Serve the artifact locally at root and under a path prefix.
3. Run the public-demo desktop and mobile Playwright smoke checks.
4. Verify no requests point to local filesystem paths.
5. Verify no requests point to raw repository asset URLs.
6. Deploy `public-demo/` to `factionos-public-demo` with Wrangler.
7. Verify the returned preview URL and `https://demo.faction-os.com/`.
8. Verify `sw.js` installs and scopes to the public demo path.
9. Verify offline reload after one online load.
10. Confirm `CACHE_VERSION` was bumped if the precache list changed.

## Phase 08 Production-Hosted Smoke

After deployment, run the sanitized hosted smoke command from the repository root:

```bash
npm run release:hosted-smoke -- --target public-demo
```

For JSON evidence:

```bash
npm run release:hosted-smoke -- --target public-demo --json
```

The public demo target checks HTTPS URL shape, shell markers, `sw.js` availability, `CACHE_VERSION` discovery, local endpoint leak markers, and raw repository asset leak markers. Output records only the target id, safe hostname, status, booleans, timing bucket, docs path, and issue codes.

Use `--no-network` only to record an unavailable no-claim summary. A no-network summary does not prove the deployed Pages surface is available. Local static serves, Playwright browser checks, GitHub Pages fallback checks, and media gates remain useful prerequisites, but they are not production-hosted Pages evidence.

Cloudflare Pages rollback readiness remains manual: keep the last known-good commit and Pages deployment available, rerun media and public-demo gates, and record only sanitized smoke output after rollback. Do not track raw Cloudflare dashboard/API output, account ids, zone ids, API tokens, request bodies, local paths, logs, backups, exports, or replay buffers.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://faction-os.gitbook.io/faction-os-docs/public-demo/docs_public-demo/deployment.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
