# 2026-03-28 Daily Notes

## Heartbeat ~03:00 UTC

### GRO-161 — Deployment pipeline investigation (RESOLVED)
- Investigated "[BLOCKED] No deployment pipeline for PR-merged code to groombook-dev"
- Found CI workflow on `main` already has `docker` + `deploy-dev` jobs
- `deploy-dev` runs on self-hosted `runners-groombook`, uses kubectl to patch deployments in `groombook-dev`
- Pipeline triggers via PR #136 (`feature/gro-118-better-auth` → `main`) — any push to the feature branch triggers CI
- CI run `23675958554` completed all 6 jobs including deploy-dev
- groombook-dev now running `pr-136` images (api + web + migrate) which include PR #140 fix
- Closed GRO-161 as done

### GRO-118 — Better-Auth status
- Dev environment deployed with `pr-136` images (includes PR #140 staff resolution fix)
- Reassigned GRO-156 to Lint Roller for QA re-verification — previous QA review blocked on 403s due to stale dev deployment
- Commented on PR #136 notifying that dev is updated and requesting fresh QA review
- **Blocking CTO review:** (1) Lint Roller QA approval on PR #136, (2) Shedward UAT sign-off

### GitHub triage
- groombook/groombook: no open issues, 1 open PR (#136 — tracked as GRO-118)
- groombook/infra: no open issues or PRs
- All items tracked — nothing to create

## Heartbeat ~03:25 UTC

### GRO-156 — QA Review PR #140 (RESOLVED)
- Woke on `issue_assigned` for GRO-156 (blocked — Flea Flicker escalated re: PR #136 CHANGES_REQUESTED)
- PR #140 already merged into `feature/gro-118-better-auth` branch at 02:50 UTC
- CI on PR #136 fully green: all 6 jobs pass including deploy to groombook-dev
- Verified dev environment via Playwright:
  - Staff page → 200 (6 staff listed) — GRO-153 403 regression fixed
  - Clients page → 200
  - Services page → 200 (10 services)
  - Appointments page → 200 (weekly calendar)
- Closed GRO-156 as done

### GRO-118 — Better-Auth: review pipeline kicked off
- Created GRO-164: QA re-review of PR #136, assigned to Lint Roller (high priority)
- Created GRO-165: UAT re-review of PR #136, assigned to Shedward (high priority)
- Posted status update on GRO-118
- Once both QA gates pass → CTO final review → hand off to CEO for merge

### GitHub triage (03:25 UTC)
- All 4 repos checked (groombook, infra, .github, groombook.github.io): no untracked items

## Heartbeat ~11:28 UTC

### GRO-177 — Postgres storage corruption (CRITICAL, IN PROGRESS)
- Woke on board comment: PVCs deleted, CNPG object needs delete/recreate
- Branch `fix/postgres-recreate-gro-177` already had two-commit approach (remove then re-add postgres-cluster.yaml)
- PR #39 (groombook/infra) was CLEAN and MERGEABLE — merged via squash
- Net change: re-adds `postgres-cluster.yaml` to kustomization with deploy version `2026.03.28-gro177`
- **Awaiting Flux reconciliation** to verify fresh CNPG cluster deploys with clean storage
- Migrate and seed jobs have bumped deploy versions — will re-run automatically

### GRO-178 — Automated CD (BLOCKED)
- Engineer (Flea Flicker) implemented CD job in `ci.yml` but cannot push workflow files
- GitHub App tokens lack `workflows` permission — platform restriction
- Posted CTO assessment: recommended board grant `workflows: write` to GitHub App
- Alternative: re-introduce Flux image automation (removed in infra PR #22)
- Set to `blocked` — needs board action

### GRO-174 — Verify groombook-dev deploy (BLOCKED, SKIPPED)
- Last comment was my blocked update (auth secrets missing), no new context — skipped per dedup rule

## Heartbeat ~12:20 UTC

### GRO-177 — Postgres corruption fix (BLOCKED — needs board)
- Verified cluster state: `groombook-postgres` Cluster object was **never deleted** — `creationTimestamp` still 2026-03-21
- Root cause: Flux reconciled PR #38 (remove) and PR #39 (re-add) as a single state change — net result was no-op
- PVCs stuck in `Terminating` (board deleted them, but pods still mount them → finalizer blocks)
- Both instances report `isPrimary: false`, spamming I/O errors every second
- Flux shows `Applied revision: main@sha1:de6cadea...` — reconciled successfully, but saw no diff
- **Resolution requires cluster admin:** `kubectl delete cluster groombook-postgres -n groombook`
- Once deleted, Flux will recreate fresh Cluster from manifest on next reconcile
- Agents only have read access to `groombook` (prod) namespace — escalated to board
- Updated GRO-177 to `blocked`

### GRO-178 — Automated CD (DONE)
- Already marked done. PR #147 still open — QA (Lint Roller) approved, awaiting UAT + CTO approval before merge

### GRO-181 — Deploy latest images (BLOCKED on GRO-177)
- Assigned to Flea Flicker, correctly blocked waiting for postgres fix
- No action needed

### GRO-174 — Verify groombook-dev deploy (BLOCKED, SKIPPED)
- No new context since last update — skipped per dedup rule

### GitHub triage (~12:20 UTC)
- groombook/infra: no open issues or PRs
- groombook/groombook: 4 open PRs, all tracked in Paperclip
  - PR #147 (GRO-178): QA approved, no UAT sign-off → skip CTO review
  - PR #146 (GRO-166): QA requested changes → not ready
  - PR #145 (GRO-179): QA approved, flagged scope creep (unrelated UI changes) → no UAT sign-off → skip
  - PR #144 (GRO-118/GRO-174): no QA approval → not ready

### Lesson learned
- Two-step GitOps delete/recreate (remove resource in one PR, re-add in next) does NOT work if both PRs merge close together — Flux reconciles the final state, not the intermediate states. Need to ensure Flux reconciles between the two merges, or use a fundamentally different approach (e.g., rename the resource, or manually delete the object first).

## Heartbeat ~12:40 UTC

### GRO-177 — Postgres storage corruption (RESOLVED)
- Woke on board comment: `kubectl delete cluster groombook-postgres -n groombook` was run
- Cluster object was gone, Flux hadn't reconciled yet (1h interval, last reconcile was 23m ago)
- Pushed deploy version bump (`f11771a`) to trigger Flux reconciliation via new commit
- Waited for GitRepository poll (15m interval) — Flux picked up new revision
- CNPG cluster recreated: 3/3 instances healthy in ~4 minutes
- Old failed jobs (migrate-schema, seed-test-data) were immutable — couldn't be updated by Flux
- Renamed jobs with `-gro177r2` suffix (`38cd23e`) so Flux creates new ones and prunes old
- Both jobs completed successfully: migrate (8s), seed (22s)
- **GRO-177 marked done**
- Commented on GRO-181 (deploy latest images) to unblock it — postgres is now healthy

## Heartbeat ~13:06 UTC

### GRO-184 — Webhook Receiver in Dev (DONE)
- CEO requested Flux webhook receiver in dev namespace
- Investigation: existing Receiver in `groombook` namespace already covers both dev and prod
  - Both Kustomizations (`groombook-dev`, `groombook-prod`) are in `groombook` namespace
  - Both reference same `GitRepository/groombook`
  - Existing Receiver triggers that GitRepository on push → cascades to both Kustomizations
- Only remaining piece: GitHub webhook configuration on `groombook/infra` repo (board task)
- Marked GRO-184 as done

### GRO-176 — Deployment (IN PROGRESS)
- 4/5 subtasks done: GRO-177, GRO-178, GRO-179, GRO-180
- GRO-181 (deploy latest images): PR #40 has merge conflict (3 behind main from GRO-177)
  - Reassigned to Flea Flicker to rebase — QA approval will be dismissed
- Created UAT tasks:
  - GRO-185: UAT for PR #145 (seed idempotency + UI scope creep) → Shedward
  - GRO-186: UAT for PR #147 (CD pipeline) → Shedward

### GRO-174 — Verify groombook-dev deploy (BLOCKED, SKIPPED)
- No new context — skipped per dedup rule

### GitHub Triage (~13:06 UTC)
- groombook/infra: PR #40 (GRO-181) — merge conflict, reassigned to engineer
- groombook/groombook: 4 open PRs, all tracked
  - PR #147 (GRO-178): QA approved, created UAT task GRO-186
  - PR #146 (GRO-166): QA changes requested (needs image deploy first = GRO-181)
  - PR #145 (GRO-179): QA approved with scope creep flag, created UAT task GRO-185
  - PR #144: lint failure — created GRO-187 for Barkley to fix TypeScript errors in portal.ts
- groombook/.github, groombook.github.io: no open issues or PRs

## Heartbeat ~13:39 UTC

### GRO-176 — Deployment (IN PROGRESS)
- Reviewed PR #147 (CD job, GRO-178) — posted **changes-requested** with 3 bugs:
  1. `--head "groombook-engineer[bot]:..."` fork prefix on same-repo branch — PR creation will fail
  2. `--auto-merges-branch=main` is not a valid `gh pr create` flag
  3. Sed pattern `[a-f0-9]*` won't match current job annotations (e.g. `gro177` has non-hex chars)
- Subtask status: GRO-177 done, GRO-178/179 PRs need author fixes, GRO-180 done, GRO-181 active (Shedward resolving merge conflict on infra PR #40)

### GRO-174 — Verify groombook-dev deploy (BLOCKED, SKIPPED)
- No new context — skipped per dedup rule

### GRO-188 — UAT run-lock issue (ALREADY DONE)
- Wake task was already done — no action needed

## Heartbeat ~15:49 UTC

### GRO-191 — Flux Image Automation (CANCELLED)
- Woke on `issue_assigned` for GRO-191 (implement Flux image automation)
- Board comment (pre-dating CEO delegation): "Flux image tag automation is denied. Intentional updates to the flux manifest at the point at which new changes are pushed is the policy and will not change. Update agent instruction bundles if needed."
- Cancelled GRO-191 per board directive
- Updated INFRASTRUCTURE.md with explicit policy: no ImageRepository/ImagePolicy/ImageUpdateAutomation CRDs
- Commented on parent GRO-190 (Image Tagging/Pinning) about the board decision

### GRO-174 — Verify groombook-dev deploy (DONE)
- Merged infra PR #42 to main — Better-Auth config now persistent in Flux
- Verified: API auth endpoints working (`get-session` returns null, `sign-in/social` returns Authentik URL)
- All auth secrets mounted from `groombook-auth-dev` sealed secret
- Remaining app issue: web frontend `/login` still renders DevLoginSelector instead of redirecting to Authentik — app code bug, not infra

### GRO-176 — Deployment (IN PROGRESS)
- Subtask status: GRO-177 done, GRO-180 done, GRO-178/179 in_progress (other agents), GRO-181 todo (other agent)
- Prod still on old images (2026.03.19-ea54506) — waiting on GRO-181
- Both dev and prod web frontends show DevLoginSelector — app code needs login page fix to use social sign-in

## Heartbeat ~20:17 UTC

### GRO-209 — Demo assets for "How It Works" section (BLOCKED)
- Assessed both environments for screenshot capture:
  - **Production** (`groombook.farh.net`): Blank page — JS bundles hardcode `http://localhost:3000` for API, prod lacks nginx `sub_filter` workaround
  - **Dev** (`groombook.dev.farh.net`): `AUTH_DISABLED=false` — requires Authentik login, agents can't authenticate interactively
- Captured one usable customer portal screenshot (session from prior test), but groomer admin views inaccessible
- Created GRO-210 (enable AUTH_DISABLED on dev) → immediately cancelled as superseded by CEO's GRO-192 / infra PR #45
- Closed infra PR #46 (superseded by PR #45)
- GRO-209 remains blocked until infra PR #45 merges

### GRO-198 — OOBE/Super User (IN PROGRESS)
- GRO-201 (schema): PR #150 submitted by Barkley, awaiting QA review
- GRO-203/205/206/207/208: All in backlog, blocked on GRO-201 merge
- Posted status update comment on GRO-198

### PR Reviews
- **PR #147** (CD job, GRO-178): Re-reviewed — Bugs 1, 3, minors fixed. One remaining: `--enable-auto-merge` not valid `gh pr create` flag. Submitted CHANGES_REQUESTED. Reopened GRO-178, assigned to Flea Flicker.
- **PR #145** (seed idempotent): QA re-approved after PetForm fix (commit 3a24ed0). UAT can't verify until dev deploy works (blocked on GRO-192).
- **PR #150** (is_super_user schema): No reviews yet — needs QA first.
- **PR #151** (groomer RBAC fix): No reviews yet — 24 commits, needs QA first.

### Critical Path
- Infra PR #45 (GRO-192) is the key blocker — reverts dev to AUTH_DISABLED=true and adds prod Better-Auth config. Unblocks demo assets, UAT verification, and prod functionality.

## Heartbeat ~20:39 UTC

### GRO-198 — OOBE/Super User (IN PROGRESS)
- **Merged PR #150** (GRO-201 schema) — CTO review + merge. QA approved, all 190 tests pass, CI green.
- Unblocked GRO-203 (RBAC middleware, Barkley) and GRO-205 (OOBE flow, Flea Flicker) — both set to `todo`
- Pipeline: GRO-201 done → GRO-203 + GRO-205 can run in parallel → GRO-206 → GRO-207 → GRO-208

### GRO-192 — Infra PR #45 (MERGED)
- **Merged infra PR #45** — CTO review + merge. Dev reverted to AUTH_DISABLED, prod Better-Auth via SealedSecret.
- This was the critical path blocker for dev deployments and UAT verification.
- Commented on GRO-192 (CEO's task) notifying of merge.

### GRO-162 — Groomer RBAC bug
- PR #151 has merge conflicts after PR #150 merged (test fixture isSuperUser field additions)
- Commented on PR requesting rebase from engineer

### GRO-178 — CD job (PR #147)
- Still has `--enable-auto-merge` bug from CTO re-review
- Reassigned from Lint Roller (QA) to Flea Flicker (engineer) — this is an engineering fix, not QA work
- Provided fix guidance: use `gh pr merge --auto --squash` as separate command after `gh pr create`

### Other PRs
- PR #145 (seed idempotent): CHANGES_REQUESTED, waiting on author
- PR #146 (reschedule buttons): CHANGES_REQUESTED, waiting on author
- PR #147 (CD job): CHANGES_REQUESTED, reassigned to Flea Flicker
- PR #148 (helm timeout): REVIEW_REQUIRED, no reviews yet — needs review

## Heartbeat ~20:44 UTC

### GRO-147 — Deployment rollout timeout (DELEGATED)
- Woke on `issue_assigned` for GRO-147 (CI deploy timeout)
- Context: CEO already opened PR #148 with `progressDeadlineSeconds: 300` on Helm templates
- Remaining: two-line CI fix (`kubectl rollout --timeout=120s` → `300s`)
- Created GRO-212 subtask, assigned to Barkley Trimsworth with exact diff
- PR #148 needs rebase on main (carries stale auth diffs from branch history)
- Commented on PR #148 with rebase instructions

### GRO-198 — OOBE/Super User pipeline update
- PR #152 now has 3 commits: schema (GRO-201), OOBE wizard (GRO-205), RBAC middleware (GRO-203)
- All CI green, CTO approved PR #152 (note: premature — should wait for QA/UAT gate)
- Posted process correction comment on PR #152
- Released stale execution lock on GRO-203, moved to `in_review`
- GRO-205 already done (Flea Flicker)
- Unblocked GRO-206 (Super User Management UI), assigned to Flea Flicker as `todo`

### GRO-209 — Demo assets (UNBLOCKED, REASSIGNED)
- Infra PR #45 merged → dev environment functional with AUTH_DISABLED
- Reassigned to Shedward Scissorhands for Playwright screenshot capture
- 3 screenshots needed: appointment booking, client portal, waitlist

### PR Reviews
- **PR #152** (GRO-203 schema+RBAC+OOBE): CTO approved (premature — QA/UAT not done yet). All CI green. Branch protection blocks merge.
- **PR #151** (GRO-162 groomer RBAC): CONFLICTING — commented requesting rebase
- **PR #148** (GRO-147 timeout): BEHIND — commented requesting rebase + CI timeout push

### Lesson learned
- CTO Review Gate: do not approve PRs before QA (Lint Roller) and UAT (Shedward) have signed off. Saved as feedback memory.

## Heartbeat ~21:07 UTC

### GRO-192 — P0 Auth Fix (BLOCKED on 2nd approval)
- Woke on `issue_assigned` for GRO-192 (critical, blocked → CEO escalated P0)
- Reviewed PR #144 diff: auth middleware skip for /api/auth/, toNodeHandler→auth.handler sub-app mount, OIDC_INTERNAL_BASE split-horizon, LoginPage replaces signIn.social(), relative baseURL
- Approved PR #144 as groombook-cto
- Updated branch with main (was BEHIND), all 6 CI checks passed
- **Blocked:** Branch protection requires 2 approving reviews from write-access users. cpfarhood's earlier approval was DISMISSED on branch update. Need cpfarhood to re-approve.
- Posted GitHub comment requesting re-approval
- Status: blocked on 2nd approval

### GRO-198 — OOBE/Super User (IN_PROGRESS)
- PR #152 still has 1 TypeScript error: `ContentfulStatusCode` not exported from `hono` in setup.ts
- Previous 3 fix commits (e9fac0e, 32ed39a, a540537) did not resolve it
- Created GRO-214 and assigned to Barkley Trimsworth to fix the import
- QA (Lint Roller) has CHANGES_REQUESTED pending CI fix

### GRO-147 — API Rollout Timeout (BLOCKED)
- GRO-212 (subtask, assigned Barkley) blocked on GitHub App `workflows` permission
- groombook-cto App cannot push to `.github/workflows/ci.yml`
- Commented with options: grant workflows permission, manual push, or reassign
- Set GRO-147 to blocked

### Delegations this heartbeat
- GRO-214 → Barkley Trimsworth: Fix ContentfulStatusCode TS error in PR #152

## Heartbeat ~23:16 UTC

### GRO-198 — OOBE/Super User (IN PROGRESS)
- PR #152 CI broken by portal commits from Barkley (GRO-218 work):
  - Commits `e0c8fff3` (portal real API calls) and `607f458f` (route restore) introduced 16 TS errors in `portal.ts`
  - Wrong column names: `isActive`→`active`, `weight`→`weightKg`, `groomerNotes`/`reportCardId`/`photoUrl`/`notes`/`dueDate` don't exist
  - `Object.groupBy()` not in target lib
  - All portal tests returning 404 (routes not registered)
- CI runs 23696279097 and 23696514405 both failed
- Created **GRO-220** (critical, assigned to Barkley): fix all portal.ts TS errors
- Requested changes on PR #152 with full error table

### GRO-147 — API Rollout Timeout (BLOCKED, SKIPPED)
- No new context since last blocked update — skipped per dedup

### PR Merges
- **PR #147** (CD job, GRO-178): **Merged** to main via squash. CI running on main (run 23696580827). This enables automated infra tag updates.

### PR Reviews
- **PR #151** (GRO-162 groomer RBAC): **Changes requested** — 38 files changed, massive scope creep (auth middleware rewrite, zod v4, Better-Auth, portal changes). Needs rebase on main and strip to RBAC-only fix.
- **PR #145** (seed idempotent): Has merge conflicts — needs rebase
- **PR #148** (helm timeout): Still has stale auth diffs from branch history, CTO changes requested still open

### Delegations this heartbeat
- GRO-220 → Barkley Trimsworth: Fix 16 TS errors in portal.ts on PR #152 branch
