Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,6 @@ X_SOURCE=mock
HOST=127.0.0.1
PORT=8787

# Optional now; required before exposing the gateway unless Cloudflare Access is used.
# Required before exposing the gateway. Generate a private 43-character base64url key.
GATEWAY_BEARER_TOKEN=
ALLOWED_ORIGINS=http://127.0.0.1:5173,http://localhost:5173
12 changes: 7 additions & 5 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,24 +32,26 @@ switch package managers without an explicit migration task.
## Non-negotiable boundaries

- Never commit or print X cookies, browser profiles, access keys, Cloudflare
credentials, relay catalogs, `.env` files, generated `dist/`, or `.ehpk` files.
credentials, relay catalogues, `.env` files, generated `dist/`, or `.ehpk` files.
- Keep `twitter_api_safe_relay` loopback-only. Only the bearer-authenticated Doge
gateway may be exposed through a tunnel.
- Public G2 builds must not contain a maintainer Gateway URL or access key. Users
configure and persist their own authenticated Gateway pairing on-device.
- Validate external data at boundaries using the shared contract. Do not pass
raw X responses, cookies, or internal headers to the G2 client.
- A build does not update a running production Gateway. Restart it, then verify
authenticated and tokenless behavior before claiming deployment success.
- Simulator, package, Hub upload, and physical-glasses behavior are separate
authenticated and tokenless behaviour before claiming deployment success.
- Simulator, package, Hub upload, and physical-glasses behaviour are separate
evidence. State clearly which one was actually verified.

## Working agreement

- Preserve unrelated changes and keep each change reviewable.
- Add or update regression tests for behavior changes. Prefer observable
- Write all maintained documentation in British English; follow the language
guidance in `docs/development.md`.
- Add or update regression tests for behaviour changes. Prefer observable
contract tests over implementation-detail assertions.
- Run focused checks while iterating, then `npm run verify` before finalizing.
- Run focused checks while iterating, then `npm run verify` before finalising.
- For release-affecting changes, run `npm run verify:release` and report the
package hash; never stage the generated package.
- Record lasting architecture or operational knowledge in the owning document
Expand Down
354 changes: 155 additions & 199 deletions README.md

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions apps/g2/AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ The glasses UI is rendered through the Even Hub SDK, not through the phone DOM.
## Read first

- Root `AGENTS.md` and `docs/INDEX.md`
- `README.md` sections “操作”, “Public buildとGateway pairing”, and
“Private buildとBeta build”
- `docs/reader-guide.md` for controls and pairing
- `docs/deployment.md` for packaging and Even Hub testing
- `app.json` and `app.production.json` before changing permissions or versions

## Invariants
Expand Down
4 changes: 2 additions & 2 deletions apps/gateway/AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ G2 client and `twitter_api_safe_relay` on loopback.

- Root `AGENTS.md` and `docs/INDEX.md`
- `docs/gateway-protocol.md`
- `README.md` sections “Security defaults” and “Maintainer deployment”
- `docs/security.md` and `docs/deployment.md`

## Invariants

Expand All @@ -29,7 +29,7 @@ G2 client and `twitter_api_safe_relay` on loopback.
- Focused route/security test: `npm test -- apps/gateway/src/<name>.test.ts`
- Type check: `npm run check --workspace @even-g2-x-reader/gateway`
- Build: `npm run build --workspace @even-g2-x-reader/gateway`
- Run root `npm run verify` before finalizing.
- Run root `npm run verify` before finalising.

After production source changes, rebuilding is insufficient: restart
`npm run production:start`, then verify authenticated `/api/v1/session` returns
Expand Down
23 changes: 14 additions & 9 deletions docs/INDEX.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,11 @@ smallest relevant reading set instead of loading the entire repository history.

## Product and architecture

- [`README.md`](../README.md) — product behavior, input model, development,
pairing, deployment, distribution, and security defaults.
- [`README.md`](../README.md) — product overview, quick start and contribution
entry points.
- [`reader-guide.md`](reader-guide.md) — controls, text, images and pairing.
- [`security.md`](security.md) — authentication, relay restrictions and data
handling.
- [`gateway-protocol.md`](gateway-protocol.md) — public Gateway protocol and
compatibility contract.
- [`../apps/g2/AGENTS.md`](../apps/g2/AGENTS.md) — G2/WebView implementation
Expand All @@ -18,11 +21,10 @@ smallest relevant reading set instead of loading the entire repository history.

## Operations

- README “すぐ試す(mock)” — deterministic local startup.
- README “live X relayへ切り替える” — login-bound Safe Relay workflow.
- README “Maintainer deployment” — named Tunnel production operation.
- README “Private buildとBeta build” — Even Hub distribution and device test
boundaries.
- [`development.md`](development.md) — deterministic local startup, live X
relay setup, authenticated preview and verification.
- [`deployment.md`](deployment.md) — HTTPS hosting, maintainer operation,
Even Hub distribution and device test boundaries.
- [`.env.example`](../.env.example) — non-secret configuration names and safe
loopback defaults.

Expand All @@ -31,15 +33,18 @@ smallest relevant reading set instead of loading the entire repository history.
- `npm run verify` — formatting, repository invariants, TypeScript, all tests,
and all builds. This is the required local and CI baseline.
- `npm run verify:release` — baseline verification, production EHPK packaging,
and artifact boundary checks.
and artefact boundary checks.
- [`.github/workflows/ci.yml`](../.github/workflows/ci.yml) — clean-install CI
using the same release verification entry point.
- [`../Backlog.md`](../Backlog.md) — durable outcomes that still require real
hardware or external validation.

## Knowledge ownership

- Put current user-visible behavior and operator guidance in `README.md`.
- Keep the product overview and quick start in `README.md`; put detailed reader,
development, deployment and security guidance in the linked guides above.
- Write maintained documentation in British English. Preserve exact identifiers,
commands, UI labels and third-party legal text.
- Put wire compatibility rules in `gateway-protocol.md` and executable schemas.
- Put package-specific agent constraints in the nearest `AGENTS.md`.
- Put durable unfinished outcomes in `Backlog.md`; keep it under 20 items.
Expand Down
4 changes: 2 additions & 2 deletions docs/agent-harness.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ does not depend on a particular agent vendor or a hidden prompt bundle.
4. **Fast feedback** — focused Vitest and workspace type/build commands support
short edit-test loops.
5. **Admission control** — `npm run verify` is the one baseline definition of
done; `npm run verify:release` adds package and artifact checks.
done; `npm run verify:release` adds package and artefact checks.
6. **Independent enforcement** — GitHub Actions installs from the lockfile and
invokes the same release verification command on a clean runner.
7. **Reproducible dependencies** — `.node-version` and `packageManager` pin the
Expand All @@ -34,7 +34,7 @@ does not depend on a particular agent vendor or a hidden prompt bundle.
as interchangeable.
- The structure remains lightweight enough for this small monorepo. Add a new
harness layer only after a measured failure shows that current tooling cannot
express or enforce the needed behavior.
express or enforce the needed behaviour.

## Maintenance rule

Expand Down
109 changes: 109 additions & 0 deletions docs/deployment.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
# Deployment and distribution

## Hosting model

Live Doge requires a running Mac, a signed-in Safe Relay browser and a Doge
gateway. Keep the Mac powered and connected to the network when using the
glasses away from home. The iPhone and glasses reach that backend over HTTPS.

Expose only the gateway at `127.0.0.1:8787`. Safe Relay must remain on
`127.0.0.1:6900` and must never be connected directly to a tunnel. See the
[security model](security.md).

Public G2 packages contain no preset gateway origin or access key. Each user
provides an HTTPS gateway implementing the [v1 contract](gateway-protocol.md)
and pairs it through the phone companion. X cookies remain on the gateway host.

## Maintainer deployment

The repository's `production:*` helpers target the maintainer's configured
named Cloudflare Tunnel at `https://doge.h1ka.ru`. This is a server-side
operational setting, not a default destination for public builds. The start
script expects the existing tunnel credentials on the maintainer's Mac;
it does not provision a new tunnel for another host.

For your own installation, provide your own HTTPS tunnel or reverse proxy to
the gateway. Configure `GATEWAY_BEARER_TOKEN` and accept the installed Even
WebView's origin. `ALLOW_BEARER_CORS=1` supports varying WebView origins while
keeping bearer authentication mandatory. The
[server entry point](../apps/gateway/src/server.ts) and
[configuration example](../.env.example) define the available settings.

On the configured maintainer host, first generate or reuse the persistent Doge
key and copy it to the clipboard:

```sh
npm run production:key
```

The script stores the key in `var/doge-access-key` with file mode `600` and
does not print it. In the Even App's Doge companion, enter the configured
HTTPS origin, paste the key and select **Save and test connection** once the
gateway is running.

With Safe Relay running and signed in, prepare the catalogue and build, then
start the gateway and named tunnel:

```sh
npm run relay:sync
npm run build
npm run production:start
```

The start script checks the local authenticated timeline, public health,
rejection of a tokenless timeline request and success of an authenticated
timeline request. It requires port 8787 to be free.

After changing gateway source, rebuild and restart `production:start`. A
running Node process keeps the code loaded from `dist/server.js`; building
alone does not update it. Confirm that authenticated `/api/v1/session` returns
HTTP 200 and a tokenless request returns HTTP 401 before treating an update
as deployed.

## Packaging and distribution

For local development packaging:

```sh
npm run verify
npm run pack:g2
```

For a package intended for distribution:

```sh
npm run verify:release
```

Both write `apps/g2/doge.ehpk`. Generated packages and build outputs are
excluded from Git. Record the package hash when reporting a release build.

The development manifest permits only the loopback mock gateway. The tracked
production manifest, `apps/g2/app.production.json`, allows user-selected HTTPS
services through its `https://` network whitelist. Do not embed a maintainer
origin or access key in frontend source, build-time variables or packages.

## Even Hub testing

Use a Beta tester group containing only your own Even account to evaluate the
installed app before submitting it to the Store:

1. Run `npm run verify:release`.
2. Create a Beta tester group in Even Hub and add your account's email address.
3. Upload `apps/g2/doge.ehpk` as a build and push it to the group.
4. In the iPhone Even App, open **Me → Beta tester → Doge → Install**.
5. Start Doge from the glasses home screen and pair your gateway in the phone
companion.

Validate saved settings restoration, recovery from the background, phone
locking and profile rendering on physical glasses before Store submission.
Use the bundled [Doge icon](../apps/g2/public/doge-icon.png) for the listing.

Beta and Private testing are distinct Hub workflows. Consult the official
[Beta testing](https://hub.evenrealities.com/docs/test/beta-testing) and
[Private testing](https://hub.evenrealities.com/docs/test/private-testing)
guides for current eligibility, distribution and lifecycle rules.

Package verification, Hub upload, simulator testing and physical-device
testing are separate outcomes. Track outstanding hardware checks in
[`Backlog.md`](../Backlog.md).
127 changes: 127 additions & 0 deletions docs/development.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
# Development

## Requirements

- Node.js from [`.node-version`](../.node-version) and npm from the
`packageManager` field in [`package.json`](../package.json).
- For physical-device testing, an Even Hub-compatible Even App paired with
Even G2 glasses.
- For local pairing and interaction, the Even Hub simulator installed by
`npm ci`. A regular browser alone does not provide the required Even SDK bridge.
- For live X data, Safe Relay and a dedicated signed-in browser session.
- For the live-device preview, `cloudflared` available on your path. The
preview and production helper scripts target macOS.

Run commands from the repository root. Install dependencies with `npm ci`;
retain `package-lock.json` and the existing package manager.

## Mock development

Follow the [quick start](../README.md#quick-start) to generate a development
bearer key, start both services and pair the companion inside the simulator.
The quick start sets `X_SOURCE=mock` explicitly, so an existing shell setting
cannot select live X data. Mock mode requires no X connection.

| Service | Local address |
| ----------------------------------- | ----------------------- |
| Gateway | `http://127.0.0.1:8787` |
| Vite companion | `http://127.0.0.1:5173` |
| Safe Relay, when started separately | `http://127.0.0.1:6900` |

The development key is generated in the shell and passed to the gateway through
`GATEWAY_BEARER_TOKEN`. Keep that shell open to reuse it. A new key requires
updating the companion pairing. Never reuse a development key for a public
gateway.

See [`.env.example`](../.env.example) for configuration names. The commands here
pass values through the shell; the gateway entry point reads `process.env`.

## Connect live X data

Doge uses a dedicated Playwright Chromium profile rather than your everyday
browser profile. Install Chromium and start Safe Relay:

```sh
npx playwright install chromium
npm run relay:login
```

Sign in to X in the new Chromium window. Once `https://x.com/home` is visible,
leave the window open. Closing the browser or stopping the command with
`Ctrl-C` also stops the relay.

The session is stored in `var/relay-profile`. It contains X cookies and local
storage, so the entire directory is excluded from Git.

In a second terminal, check the relay and refresh its query catalogue:

```sh
npm run relay:check
npm run relay:sync
```

Stop the mock gateway before starting the live gateway on the same port. In
the shell holding your development key, run:

```sh
X_SOURCE=relay npm run dev:gateway
```

Start the companion in another terminal:

```sh
npm run dev:g2
```

The catalogue records the current X query IDs and feature flags. Refresh it
when those change. `var/requests.ndjson` may contain account-derived IDs and
cursors and must remain untracked. The gateway reloads the catalogue during
operation, so catalogue synchronisation does not require a rebuild.

## Live-device preview

With Safe Relay signed in and its catalogue synchronised, build the app and
start the temporary authenticated preview:

```sh
npm run build
npm run preview:live
```

Stop any other gateway on port 8787 first. The preview creates a random
256-bit bearer token, starts the gateway and opens a disposable Cloudflare
Quick Tunnel. It checks the authenticated live timeline before opening a QR
image on the Mac.

The token is embedded in the QR's URL fragment, which is not sent to the tunnel
server. It is not printed in the terminal. The temporary image has file mode
`600`; keep it private. Scan it for the preview, then save and test the same
HTTPS origin as the Gateway URL in the phone companion. API calls use the
bearer token in the `Authorization` header.

Press `Ctrl-C` to stop the gateway and tunnel and remove the QR image. The
temporary token stops providing access when that gateway exits. Quick Tunnels
have no fixed URL or availability guarantee; use the
[deployment guide](deployment.md) for persistent operation.

## Verification

```sh
npm test -- apps/g2/src/input.test.ts
npm run check --workspace @even-g2-x-reader/g2
npm run check --workspace @even-g2-x-reader/gateway
npm run verify
```

`npm run verify` checks formatting, repository invariants and TypeScript, then
runs all tests and builds all workspaces. Run it before finalising code or
documentation changes.

For a distributable package, use `npm run verify:release`. It also creates the
production EHPK and checks artefact boundaries. See
[packaging and distribution](deployment.md#packaging-and-distribution) for the
distinction between local and public manifests.

Write all maintained documentation in British English, including README files,
guides, agent instructions and backlog entries. Preserve exact API names, code
identifiers, commands, UI labels and third-party legal text.
Loading
Loading