| name | factory-ship |
| description | Ship the current branch โ validate, open a PR with a proof bundle, then either gate straight to production (auto lane) or post the preview URL and wait for Guillaume's approval (approval lane). Use when accepted work packages are committed and ready to release. |
factory-ship โ validate โ PR โ [approval] โ gate โ verify prod
Ships the current codex/<slug> branch and reports the outcome honestly.
Never declare success before the deployment status is verified.
Lanes โ pick one first
- auto โ docs, retro, factory-internal changes: gate immediately after
the PR opens.
- approval (default for feature/UI work, mandatory for PRD #493-era
feature tickets): open the PR, post the preview URL to Guillaume,
and STOP. Only run the gate after an explicit "approve #N". Mark the PR
body "DO NOT MERGE โ awaiting Guillaume's preview QA".
1. Validate (all green before any push)
cd /Users/guillaume/Github/serious-trader-ralph
bun run typecheck && bun run lint && bun run test
(cd apps/portal && bun test)
bun run build 2>&1 | tee /tmp/ship-build.log
grep -ci "unused css selector" /tmp/ship-build.log
2. PR
Push the branch and open a PR against main with the WORKFLOW.md proof
bundle: change summary, validation commands + results, local URL used for
UI verification, browser artifacts (screenshots) for UI changes, risk
notes / deferred items. Reference the ticket (Closes #N).
3. Preview URL (approval lane) โ NEVER skip the script
scripts/factory/preview.sh <pr-number>
This step is what moves the preview.trader-ralph.com alias. The domain
is NOT automatic: until the script runs for this PR it silently serves
whatever PR was QA'd last, and Guillaume tests stale code with no visible
error (happened on #520 โ the "fixed" bug reproduced because the alias
still pointed at #519's build). Only post the QA link AFTER the script
prints the (auth-enabled alias) line.
Post PR link + preview URL + concrete QA notes ("what to check") to
Guillaume. Wait. Do not gate.
4. Gate (after approval, or immediately in the auto lane)
scripts/factory/gate.sh <pr-number> [<pr-number>...]
Run in background. Multiple approved PRs can be passed at once โ the
script serializes them and refreshes each subsequent branch onto the new
main between merges.
Gate outcomes:
CHECK FAILURE โ fix on the branch, push, rerun the gate.
BLOCKED + green checks โ branch behind main (script handles this for
queued PRs; for a single PR, merge origin/main in and push) OR an
unresolved review conversation โ the codex bot reviews most PRs and
its P2s are usually right: fix, reply, resolve via GraphQL
resolveReviewThread, and the still-polling gate picks it up.
- Timeout โ it is a timeout; report it as one. Never infer success.
- Local branch delete may fail (worktrees hold
main) โ remote delete is
what matters; confirm with gh pr view N --json state,mergeCommit.
5. Report
Merge commit sha ยท main CI result ยท production deployment result โ exactly
as observed. If any step failed or was skipped, say so plainly.