This runbook covers day-two operation of the private single-instance Render deployment. Initial deployment and enrollment instructions live in Deployment. The release smoke record lives in ../test/e2e/render-smoke.md.
npm start runs the composed lifecycle through src/server.ts and src/runtime/production-bootstrap.ts. Keep the release blocked until /readyz is 200, an authorized live DM receives one reply, restart/replay checks are recorded, and the remaining Spectrum 12.7 outbound GUID limitation is accepted or removed. A healthy /healthz alone is insufficient.
Run from a trusted operator environment:
curl --fail --silent "https://<service-host>/healthz"
curl --silent --show-error "https://<service-host>/readyz"Expected composed-service states:
/healthzis HTTP 200 whenever the Node process can serve diagnostics./readyzis HTTP 200 only when every critical component isok./readyzis HTTP 503 during shutdown, missing owner setup, a Photon installation not validated for the current owner revision, missing/expired Codex auth, capability loss, database failure, migration/queue failure, invalid disk/workspace storage, or Spectrum disconnect.- Supermemory may be
disabledordegradedwithout blocking the operational pipeline.
The readiness response includes detailed component state, bounded error codes, and remediation actions. The dashboard reports setup status, active device codes and verification URLs, the assigned number, and masked owner state. Treat a raw owner phone, provider credential, database credential, message, unrestricted provider error, or private path in these responses as a security incident.
Dashboard setup mutations require same-origin and fetch-metadata validation.
The owner card shows either the setup form or only the masked active phone. The saved personal phone is the only authorized iMessage sender; the separately assigned Photon number is the destination shown at completion. The phone is entered in the dashboard and is not a fresh-deployment environment value.
To replace the owner, open Change phone number. U.S. owners can enter a normal 10-digit number without +1; international owners select Not in the U.S.? and choose their country. Save the new value, then reconnect Photon for that owner revision and verify one message from the new owner plus rejection of the previous owner. The replacement transaction increments the owner revision, activates the new encrypted identity, revokes prior owner-phone identities, and invalidates the old Photon binding while leaving collaborator identities unchanged. Never place a phone in a URL, log, or support ticket.
-
Record the outgoing application commit and current
/readyzresponse. -
Read new migration notes and confirm backward compatibility.
-
Confirm a database recovery point exists.
-
Validate
render.yamlin an authenticated Render CLI workspace:render workspace set npm run render:validate -
Run the required local test suite and record skipped tests.
-
Deploy the reviewed commit. Confirm the pre-deploy migration succeeds before the service starts.
-
Require
/healthzHTTP 200 and/readyzHTTP 200. -
Send one authorized, non-mutating test message only after readiness passes.
-
Restart the service and repeat readiness plus one follow-up turn.
The Render CLI requires an explicit/default workspace. A validation attempt without one is not Blueprint validation evidence.
Render sends SIGTERM using its platform-managed shutdown delay for this disk-backed service. The composed bootstrap marks readiness false and aborts active work before running stop hooks in this order:
- Spectrum receive loop.
- Active Codex work.
- Outbound cursor checkpoint.
- pg-boss workers.
- PostgreSQL connections.
- HTTP listener.
After restart, require reconciliation of undrained inbound messages, queued planning chains, missing approval request/action jobs, resumable outbound batches, and unpublished memory curation candidates before readiness returns to 200. Queue workers are created once per process; only Spectrum intake is restarted by activation recovery. Verify no stale chain sends, no action executes twice, and no outbound cursor moves backward.
Symptoms: /healthz 200; /readyz 503; the dashboard reports Codex authentication needs attention; Spectrum startup remains paused.
ChatGPT mode:
npm run codex:login
npm run codex:statusComplete device login, verify $CODEX_HOME/auth.json remains mode 0600, then refresh model settings. One refresh must produce one catalog persistence and only the required effective-pair probe. Capability recovery should start exactly one Spectrum run.
API-key mode: replace OPENAI_API_KEY in Render, restart, and rerun capability probes. Do not change CODEX_AUTH_MODE as a fallback unless that is an explicit operator decision.
Symptoms: /healthz 200; /readyz 503; Spectrum intake remains stopped; the dashboard asks for an owner phone.
For a fresh deployment, save the personal owner phone in the dashboard and continue to Photon. U.S. entry defaults to national format; international entry requires a selected country, and the server normalizes both to E.164. For an existing deployment, first verify whether OWNER_PHONE_NUMBER, the former long Render alias, or AGENT_OWNER_HANDLES is present. The runtime imports only one unambiguous E.164 value and never imports owner identity from Photon credentials. A legacy Photon credential file may be imported into the durable installation record, but Spectrum remains blocked until the provider validates it for the current owner revision. If multiple handles or an email-only handle caused migration-required state, open the dashboard and save the intended phone explicitly. Verify the masked status, current-revision Photon connection, and an authorized message before manually removing old environment values.
Symptoms: /healthz 200; /readyz 503; the dashboard reports Photon setup required, reconnecting, or an owner-revision mismatch; Spectrum intake is stopped.
- Confirm the current masked owner is correct before starting setup.
- Resume the dashboard device flow; do not create a second installation while an operation is active.
- Wait for provider validation and owner registration to commit to PostgreSQL.
- Confirm the connected installation revision equals the current owner revision.
- Verify activation starts exactly one Spectrum run. If the owner changes again, repeat setup for the new revision.
Symptoms: /readyz 503; the dashboard or private logs report SPECTRUM_STREAM_DISCONNECTED or SPECTRUM_STREAM_RESTART_EXHAUSTED.
- Check Photon provider status and the Web Service's Spectrum credentials without printing them.
- Allow the bounded supervised reconnect policy to run.
- If exhausted, the activation coordinator clears active ownership and schedules bounded recovery. Restart only after recovery remains exhausted or operator intervention is required.
- Verify reconciliation and route rehydration from persisted space GUID/route phone.
- Confirm one authorized DM and check for duplicate outbound parts.
Symptoms: /healthz 200; /readyz 503; readiness or private logs report DATABASE_UNAVAILABLE; downstream startup stages do not run.
- Stop manual message execution.
- Check Render Postgres health and the dynamic
DATABASE_URLreference. - Restore connectivity and verify migrations.
- Restart the service.
- Run reconciliation and inspect safe failure counts/correlation IDs.
- Confirm queued work resumes exactly once.
Symptoms: the dashboard or private logs report memory recall unavailable/degraded; core readiness can remain healthy.
This is the required operating policy. Automated integration coverage verifies that each application retry uses a fresh abort signal and chaos coverage verifies durable candidate recovery after queue publication failure. A protected live-provider outage exercise is still separate release evidence.
- Do not stop operational messaging solely for memory unavailability.
- Verify planning used an empty memory context rather than stale cross-owner data.
- Leave projection jobs retryable; inspect redacted receipt/failure codes.
- After recovery, verify a bounded recall and one temporary add/search/delete smoke item in a test owner container.
- Never replay raw messages into Supermemory.
Symptoms: a task remains needs_approval, an approved action remains pending, or no request/execution job is visible after a queue outage.
- Do not create a replacement approval or manually edit the encrypted payload.
- Restore PostgreSQL and pg-boss, then restart or invoke normal reconciliation.
- Verify one
approval.requestjob exists for each unresolved task and oneapproval.executejob exists for each pending action execution. - Confirm the responder is the owner in the allowed space; collaborator approvals must remain rejected.
- Verify the stored idempotency key and terminal action state before considering any manual provider-side recovery.
Symptoms: /readyz 503; readiness or private logs report PERSISTENT_STORAGE_INVALID.
- Stop execution; do not create replacement Codex threads on ephemeral storage.
- Verify the
/var/datamount, ownership, space, and directory permissions. - If the disk is lost, revoke potentially exposed credentials, attach replacement storage, and re-enroll Codex.
- Recreate workspaces from trusted remotes/backups.
- Resume from bounded PostgreSQL summaries.
- Do not reset the outbound cursor manually.
- Restore Spectrum connectivity.
- Let the resumable batch job claim the persisted
start_index. - Confirm every retry uses the materialized part's original client GUID.
- Compare database part states with visible provider results; preserve evidence of any provider-level duplicate.
Roll back application and schema independently.
- Stop new execution and let graceful shutdown checkpoint state.
- Select the last known-good application commit compatible with the current schema.
- Roll back the Render deploy to that commit.
- Do not undo forward-compatible migrations merely to match code.
- If schema rollback is mandatory, stop all workers, verify a backup/recovery point, and use only the SQL in the migration's
.notes.md. - Restart, reconcile, verify both health endpoints, and run a non-mutating authorized turn.
If compatibility is uncertain, roll forward with a fix or restore the application and database together to a matched recovery point. The initial migration rollback is destructive and must not be used on a live database without an explicit data-loss decision.
When ownership changes or a credential may be exposed:
- Stop the service.
- Revoke the old ChatGPT session/API key and rotate Photon, Supermemory, encryption, and database credentials as applicable.
- Remove only the compromised Codex auth file after confirming the exact persistent path; do not delete the disk or workspace tree.
- Run the appropriate enrollment flow.
- Verify credential file permissions, status, capability probes, restart persistence, and readiness.
- Review failure/audit logs for unexpected use, without copying private payloads.
Before upgrading an existing service:
- Open the Web Service's private Environment page in Render.
- Delete both former dashboard credential variables using Render's save-without-deploy option.
- Deploy this release. Startup intentionally rejects either obsolete key, even when it is empty.
- Open the dashboard and verify owner, Photon, and ChatGPT state.
Record timestamps, commit, Render deploy ID, readiness evidence, redacted diagnostic states, correlation IDs, tests run, and whether a live provider was actually exercised. Never paste raw messages, device codes, secrets, auth files, phone/email handles, or full provider exceptions into incident tickets.
Escalate and keep execution paused when:
- authorization or outbound routing cannot be proven;
- PostgreSQL state is unavailable or inconsistent;
- a stale/canceled chain sends;
- an outbound retry changes client GUID;
- credentials appear in logs or health responses;
- the old application/schema compatibility is unknown; or
- executable composition does not match the reviewed
src/server.tsandproduction-bootstrap.tsrelease.