- staging-up.sh binds the dev server to 127.0.0.1 (tunnel-only, no public access)
and sets NEXT_PUBLIC_ENV_LABEL so the 'INTERNAL DEV / STAGING - NOT PRODUCTION'
banner shows.
- staging-tunnel.cmd: Windows launcher that opens the SSH tunnel + browser
(wired to a desktop shortcut).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The test DB mirrors prod, which can be behind master, so the latest code 500s on
columns prod doesn't have yet (e.g. poDate from the optional-PO-date feature).
- staging-up.sh runs prisma migrate deploy after install.
- refresh-test-db.sh re-applies master migrations after each nightly data copy,
so the running staging/autofix DB stays at the schema of the code under test.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Brings up pm2 'ppms-staging' on port 3200 from the latest master, against the
prod-mirror test DB in safe dev mode. Re-run to refresh to newer master.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- automation/refresh-test-db.sh: daily pg_dump of prod (pelagia) into a throwaway
mirror (pelagia_test) on pms1; cron at 03:30. ~10MB, refresh ~1s.
- Autofix clone ~/pelagia-autofix/App/.env points DATABASE_URL at pelagia_test in
safe dev mode (no Resend/SSO secrets -> console email, local storage), port 3100.
- Fix prompt: Claude may run integration tests against the test DB and start a dev
server on port 3100 ONLY; stop it by port (fuser -k 3100/tcp), never broad pkill
(production also runs a next-server on 3000).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- automation/claude-issue-watcher.sh: Linux port of the watcher (curl + jq +
flock). Same triage + fix phases. On Linux the PS 5.1 encoding/array quirks
don't apply, so it's simpler.
- Auth preflight: no-ops until Claude Code is signed in on the host (or an
ANTHROPIC_API_KEY is set), so cron can be enabled before sign-in.
- Runs on pms1 under cron every 10 min; Windows scheduled task is disabled so the
two machines don't race the Forgejo queue.
- .gitattributes pins *.sh to LF.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Portal issues now file with only the 'portal' label. The watcher runs two phases:
1. Triage — Claude reads each untriaged 'portal' issue (analysis only), posts a
requirements-breakdown comment, and routes it to 'claude-queue' (auto-fixable)
or 'interactive' (needs human steering).
2. Fix — unchanged; processes 'claude-queue' issues into PRs.
The triage breakdown is posted without the bot marker so the fix stage reads it
back as refined requirements.
PS 5.1 fixes found while validating:
- Send API bodies as UTF-8 bytes (Invoke-RestMethod mangled non-ASCII, e.g. the
em-dash in Claude's breakdown, so Forgejo rejected the JSON)
- Build the labels array body by hand (ConvertTo-Json unwraps a single-element
array to a scalar, which Forgejo rejects)
- Triage output via two plain files (label + markdown) instead of one JSON blob
(embedded-newline markdown broke ConvertFrom-Json)
- Read triage files as UTF-8; additive label POST + a guard so Set-IssueLabels
can never wipe an issue's labels
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- Get-IssueCommentsBlock includes human issue comments in Claude's prompt so
scope/repro added as comments is acted on (requested for delivery-dropdown #19)
- Critical: capture Api responses to a variable before filtering. Piping the
Api function's array output straight into Where-Object collapses all issues
into one object in PS 5.1, so the watcher tried to process #12/#8/#7 at once
- Bot status comments now carry an ASCII <!-- ppms-bot --> marker and are
filtered out (incl. legacy emoji comments via stable ASCII phrase match) so
they are never fed back as human input; script kept ASCII-only for ANSI load
- Harden numeric sort/select on issue numbers
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- Report Issue button in portal header files a Forgejo issue (portal + claude-queue labels)
- Windows scheduled watcher runs headless Claude Code on queued issues and opens a PR
- .forgejo/workflows/deploy.yml deploys v* release tags via the pms1 host runner (pm2 restart ppms)
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>