wp-durable · Stage 1 handover (2026-10-10)
Deployment
| Item | Value |
|---|---|
| Public URL | https://wp-durable-production.up.railway.app |
| Sign-in page | https://wp-durable-production.up.railway.app/auth |
| Railway workspace | stevenevans669's Projects (CLI login stevenevans669@gmail.com) |
| Project | wp-durable · bf1cda11-fb2b-4aa5-aef3-b9edd842f9b3 |
| Environment | production · 4fd7a540-5dd8-4602-b98d-37f7f2b70908 |
| Service | wp-durable · d903f418-9cd4-48e6-b9f5-f5ffaf21803e |
| Volume | wp-durable-volume · 3c073dfb-0b44-4ff0-87d5-8e471e20140f, mounted at /data (50 GB) |
| Replicas | 1 (numReplicas unset = default 1; railway.json sets numReplicas: 1) |
| App Sleeping | off (railway.json sleepApplication: false; the CLI status JSON has no field for it) |
| Cron | not a cron service (cronSchedule: null) |
| Health check | /healthz, timeout 180 s; restart policy ON_FAILURE, 10 retries |
| Build | Dockerfile, node:22-bookworm-slim, Node 22.22 in the image |
| Variables | WP_DURABLE_TOKEN (random 32 bytes, hex), PORT=8080, WP_DURABLE_MODEL=gpt-6-sol |
| Bearer token file | /Users/steven/DevTemp/wpDurable/.secrets/wp-durable-token (mode 0600, .secrets/ git-ignored) |
| Model | openai-codex / gpt-6-sol (from OPENAI_CODEX_MODELS), ChatGPT subscription via device-code OAuth |
| Credential | /data/credentials.json on the volume, mode 0600, the only copy |
| Source | /Users/steven/DevTemp/wpDurable, git, 3 commits, no remote |
Deployments (UTC): f9c98150 01:50 first deploy · 82deaa46 06:19 adds /auth · 25be23c3 06:32 redeploy (T0 step 3) · 6719f8fe 06:34 redeploy requested by piinchrome-48.
T0 results
/healthz→ok: true, storage: "ok"after the first deploy;credential: "present"after sign-in.POST /v1/submit {"content":"Reply with the single word pong.","requestId":"t0-1"}→ submission 8,doneafter about 4 s, answerpong. Usage of that call: input 39, output 5, total 44 tokens, cost $0.000128.- Redeploy
25be23c3: new container healthy within 30 s,credential: "present", submission 8 still readable. Second redeploy6719f8fe(requested): healthy at 06:35:10 UTC, credential present. - Re-POST of
t0-1after the redeploy → same submissionId 8, same answerpong, no new generation task. Verified in the database: generation tasks 9, 14, 18 map one-to-one to submissions 8 (t0-1), 13 (acc-20261010-1), 17 (acc-20261010-2). The usage increase observed at that moment (44 → 106 total tokens) came from piinchrome-48's acceptance submission 13, not from a duplicate run.
Sign-in history: the device-code request was accepted on the first attempt (no fallback). Two codes expired unapproved before Steven used the /auth page; the third was approved and stored at 06:31:07 UTC.
Deviations from the brief
- Container runs as root (node image default) so the volume is writable without a chown step.
GET /auth(public static sign-in page) andGET /→ 302/authwere added at Steven's request. All/v1/*routes remain bearer-protected; only/healthzand/authare public.- Responses carry extra fields:
/healthzaddsprovider,model,rootConversationId,uptimeSeconds;/v1/submissions/:idaddsrequestId,conversationId;/v1/conversations/:idaddsentries;/v1/auth/codex/statusaddsuserCode,verificationUri,expiresAt,intervalSeconds,finishedAt,credential. POST /v1/submitanswers202and includesstatusnext tosubmissionIdandconversationId.- Sign-in state is in memory: after a redeploy
/v1/auth/codex/statusreportsnonewhile the credential stays present. - Storage-failure handling: pi-durable 1.1.0 does not export
harness.closed/SessionFailed(the README onmainis newer). A failed storage read in/healthzreturns 503 and exits the process so Railway restarts it;onReportonly logs. credential: "expired"compares the stored access-token expiry with the clock. pi-ai refreshes on use, so "expired" is informational, not a failure.- IDs share one global sequence across records, so the first submission is id 8, not 1.
- Railway CLI warns that
railway.jsonconfig-as-code is deprecated in favour of.railway/railway.ts; it stays honoured until 2026-12-01. Not migrated in Stage 1. - Node prints one
ExperimentalWarning: SQLite is an experimental featureline at startup. - Acceptance is run by piinchrome-48; my T0 run was a pre-check. I used
railway sshonce for a read-onlynode:sqlitedump of/data/agent.sqliteto verify the task/submission mapping. - The
openai"Sign in with ChatGPT" flow was not used, per the brief change; the legacyopenai-codexprovider is the only provider registered.
Not done / out of scope
Tools, Apify, datavault, timers, Woodpecker registration, multiple conversations, non-root user, log shipping, IaC migration.