Review: dev environment -- ephemeral DB, shared Keycloak, dev URL, migration practices, port convention

review-1876-2026-07-18 Review

review needs-refinement

Verdict: NEEDS_REFINEMENT

Template Completeness

  • [x] Type -- "Feature"
  • [x] Lineage -- Standalone, identified during Sprint B validation
  • [x] Repo -- ldraney/intelligentstaffingsystems (primary) + 3 cross-repo references
  • [x] Dependencies -- #85 blocker clearly documented
  • [x] User Story -- Well-formed As a / I want / So that
  • [x] Context -- Exceptionally thorough: explains what was attempted (#77 decomposition), what fell short, current state of every relevant file, five interconnected pillars, platform patterns to study
  • [x] File Targets -- Detailed table with current state and relevance for 12 ISS-repo files + cross-repo reference table + pal-e-docs SOPs
  • [x] Feature Flag -- "none -- developer tooling, no user-facing feature"
  • [x] Acceptance Criteria -- 14 criteria
  • [x] Test Expectations -- Manual verification approach (correct for dev tooling)
  • [x] Constraints -- 7 constraints including explicit "do not decompose" directive
  • [x] Checklist -- 14 items
  • [x] Related -- Comprehensive cross-references to parent/child/sibling tickets and SOPs
All required sections for a Feature template are present and well-written.

Traceability

  • [x] story:project-setup label -- "Repo, docs, infra, and CI exist; sprints can dispatch"
  • [x] story note verified -- found in project-iss user-stories section (key: project-setup, role: Developer)
  • [x] arch:rails label -- Rails component
  • [ ] arch note MISSING -- [SCOPE] No arch-rails note exists in pal-e-docs. An arch-rails-app note exists under pal-enterprises but does not match the label exactly. Create architecture note arch-rails or align label to arch:rails-app.
  • [x] arch:infra label -- Infrastructure component
  • [ ] arch note MISSING -- [SCOPE] No arch-infra note exists in pal-e-docs. This is a known systemic gap flagged across multiple projects (iss, paldocs, landscaping-assistant). Create architecture note arch-infra for the platform infrastructure component.
  • [x] Forgejo issue -- ldraney/intelligentstaffingsystems#86, open

File Targets

  • [x] docker-compose.yml -- verified: port 9999, no Keycloak service, pgdata volume, harbor base image. All claims accurate.
  • [x] Makefile -- verified: wraps docker compose, targets include dev/setup/migrate/seed/test/ci/logs/console/lint/security. No environment-specific targets. All claims accurate.
  • [x] Dockerfile -- verified: production image, EXPOSE 3000, harbor.tail5b443a.ts.net/library/ruby-rails-build:latest base.
  • [x] config/puma.rb -- verified: port ENV.fetch("PORT", 3000) at line 32.
  • [x] config/database.yml -- verified: dev/test use DATABASE_HOST, DATABASE_USER, DATABASE_PASSWORD env vars with rails/rails defaults.
  • [x] config/initializers/omniauth.rb -- verified: registers Keycloak OIDC provider only when all KEYCLOAK_* env vars present OR in test mode. Dev without env vars skips middleware entirely.
  • [x] config/environments/development.rb -- verified: config.action_mailer.default_url_options = { host: "localhost", port: 3000 } at line 41. Port mismatch with docker-compose (9999) confirmed.
  • [x] config/environments/production.rb -- verified: config.hosts has intelligentstaffingsystems.ai and iss.tail5b443a.ts.net. No dev.intelligentstaffingsystems.ai entry yet.
  • [x] db/seeds.rb -- verified: fake keycloak_sub values (admin-dev-sub-001, client-dev-sub-002, etc.). 4 Leads, 3 CatalogEntries, sample Message threads.
  • [x] docs/local-dev-setup.md -- verified: exists, documents current 9999 workflow.
  • [x] docs/architecture.md -- verified: exists, contains port convention table showing local dev at 9999.
  • [x] docs/pipeline.md -- verified: exists, references localhost:9999 in dev workflow section.
  • [x] test/test_helper.rb -- verified: OmniAuth.config.test_mode = true, sign_in_as helper with fake subs (kc-sub-lead, etc.).
All 13 file targets exist and all described current states are accurate.

Repo Placement

OK. Issue is filed on ldraney/intelligentstaffingsystems, which is the primary repo. Cross-repo changes (pal-e-deployments, pal-e-platform, pal-e-services) are explicitly identified and the Constraints section mandates separate PRs for each. No mismatch.

Dependencies

  • #85 (board item #1875) -- listed as blocker. Currently in validation column (merged, not yet validated). The k8s secrets and CI pipeline must be confirmed working before dev environment changes can be validated against production. Dependency is correctly documented.
  • #77 (board item #1868) -- parent ticket, in todo column, marked decomposed. Its decomposition children (#78, #79, #80) are in validation/done. This ticket (#86) fills the gap that #77's decomposition missed.
  • #78 (board item #1869) -- kustomize overlays, in validation. Placeholder secrets noted.
  • #79 (board item #1870) -- dev DNS + Caddy, in validation. Terraform apply pending.
  • #80 (board item #1871) -- Makefile + docker-compose, in done.
  • No undocumented dependencies found.

Acceptance Criteria

14 criteria, all testable. Criteria 1-3, 4-5, and 12 require manual verification, which is appropriate for developer tooling. Criteria 6-9 and 11 are code-verifiable. Criterion 14 (cross-repo PRs) is verifiable via Forgejo.
The criteria are comprehensive and cover all five pillars. One potential gap: no criterion explicitly verifies that OmniAuth test mode is not used in dev when Keycloak env vars are present (i.e., that the developer truly gets real auth, not mocked auth). Criterion 1 implies this but does not make it explicit. This is minor.

Blast Radius

Port 9999 is referenced in 10+ locations across docker-compose.yml, Makefile, README.md, docs/architecture.md, docs/pipeline.md, docs/local-dev-setup.md. If the port changes, all must be updated. The ticket is aware of this scope.
The mailer URL mismatch (development.rb says 3000, docker-compose runs 9999) is a pre-existing bug that this ticket would fix as a side effect of resolving the port convention. No downstream consumers beyond the ISS app itself.
Keycloak redirect URI changes in pal-e-services affect the ISS realm only, not other clients. CORS implications are noted in the ticket.

Decomposition Assessment

By the 5-minute rule: 13 file targets across 4 repos, 14 acceptance criteria, estimated agent work well over 5 minutes. This ticket technically exceeds all three decomposition thresholds.
However: the ticket explicitly forbids decomposition in its Constraints section with a reasoned argument that the five pillars are interdependent. The user's standing preference is "stop decomposing; write inclusive tickets." The cross-repo work is separated into distinct PRs per the constraints. Within the ISS repo, the changes are cohesive -- port convention affects Keycloak redirect URIs, which affect seed data strategy, which affects the dev URL, etc.
No decomposition recommended. The 8-point sizing is appropriate for the scope.

Recommendations

  • [SCOPE] Create architecture note arch-rails in pal-e-docs for the Rails component (or align the board label to the existing arch-rails-app note). This is a systemic platform gap, not specific to this ticket.
  • [SCOPE] Create architecture note arch-infra in pal-e-docs for the infrastructure component. Also a systemic gap flagged across multiple projects.