claude/zealous-lovelace-cbc97f
needs attentionviewing older commit1328ef5 · incrementalPR #215reviewed 2026-07-03 06:26 UTC1H · 4M · 5L · 5I- Purpose
- Evolve Loop C (Review) from a cron-polled PR reviewer into a per-commit, push-triggered reviewer on a self-hosted GHA runner. Deliver the reconcile+watchdog for utility_contract_overview drift detection.
- Goal
- Per-commit review on push: 5-lens panel, markdown summary + inline PR comments, HTML dossier to dev-ops dashboard. Propose-never-merge.
- Sub-goals
- SG-1: review-panel improvement lens — DONE
- SG-2: loop-review --sha per-commit mode — DONE
- SG-3: .github/workflows/loop-review.yml push trigger — DONE
- SG-4: DevOpsStack CDK singleton (BatuDevOps) — DONE + DEPLOYED
- SG-5: Dedicated GitHub loop identity (operator-gated)
- SG-6: dev-ops.batuenergy.com dashboard (P2, code built)
- SG-7: loops.md SSOT + docs update — DONE
- What
- This incremental commit (1328ef52) addresses loop-review findings: masks DB connection strings in GHA logs via add-mask + sed redaction, fixes test race condition replacing latestRun() with runById() tracked per-suite, adds explicit invariant guard in runOverviewReconcile throwing on missing row, and hardens SECURITY DEFINER function with pinned search_path=public and schema-qualified pg_temp references.
- Why
- Previous loop-review flagged credential leak risk in watchdog workflow error logs, flaky test relying on DESC-ordered latest run (race with concurrent suites), silent empty runId on stored-procedure invariant break, and temp-table shadowing vulnerability in SECURITY DEFINER function.
- Areas
- .github/workflows/uco-drift-watchdog.yml+124−0domains/utility/src/utility-contract-overview/__tests__/utility-contract-overview.reconcile.integration.test.ts+283−0domains/utility/src/utility-contract-overview/utility-contract-overview.queries.ts+57−0packages/database/drizzle/0053_organic_changeling.sql+215−0scripts/db/uco-drift-watchdog.sql+67−0packages/database/src/schema/utility-contract-overview-reconcile.ts+70−0docs/ADRs/020-contracts-realtime-read-model.md+6−2
- Blast
- 12 files, +859/-3 across .github/workflows, domains/utility, packages/database, scripts/db
Findings · 15
security3
CREATE TEMP TABLE not schema-qualified (asymmetry with qualified references)
packages/database/drizzle/0053_organic_changeling.sql
All references use pg_temp._uco_drift but CREATE TEMP TABLE _uco_drift is unqualified. Not exploitable (PostgreSQL always creates temp tables in pg_temp), but asymmetry is a maintenance hazard.
Redaction regex misses libpq key=value DSN form
.github/workflows/uco-drift-watchdog.yml:69
sed pattern covers postgres(ql):// URIs but not key=value DSNs. add-mask is the primary protection; real risk is very low.
Test teardown deletes from audit table — confirm non-prod guard
domains/utility/src/utility-contract-overview/__tests__/utility-contract-overview.reconcile.integration.test.ts:150
afterAll deletes audit rows via service_role. Verify integration tests cannot target production DB.
conventions4
ReconcileRow type alias inside function body (should be module-scope)
domains/utility/src/utility-contract-overview/utility-contract-overview.queries.ts
Move ReconcileRow outside runOverviewReconcile to module scope for reuse.
runOverviewReconcile throws instead of returning Result<T, E>
domains/utility/src/utility-contract-overview/utility-contract-overview.queries.ts
FCIS convention requires fallible operations to return Result<T, E>. A missing stored-procedure row is a recoverable infrastructure failure.
Test helper reconcile() shadows shell naming convention
domains/utility/src/utility-contract-overview/__tests__/utility-contract-overview.reconcile.integration.test.ts:63
By FCIS convention, reconcile implies a shell. Rename to runReconcileQuery().
Raw Drizzle delete in afterAll bypasses query layer
domains/utility/src/utility-contract-overview/__tests__/utility-contract-overview.reconcile.integration.test.ts:147
Project convention: all DB operations behind query helpers in queries.ts.
tests5
No test coverage for the new throw path in runOverviewReconcile
domains/utility/src/utility-contract-overview/utility-contract-overview.queries.ts:597
The throw new Error guard is untested. Add a unit test with a stubbed db.execute returning empty results.
repairedCount === driftCount assertion fragile under concurrent suites
domains/utility/src/utility-contract-overview/__tests__/utility-contract-overview.reconcile.integration.test.ts:196
reconcile() operates on ALL orgs in DB. Concurrent suites could push total drift past the 2000-pair cap. Use toBeGreaterThanOrEqual(1) instead.
afterAll doesn't guard on undefined contractM/contractU
domains/utility/src/utility-contract-overview/__tests__/utility-contract-overview.reconcile.integration.test.ts:159
If beforeAll fails mid-way, contractM/contractU may be undefined. Guard each cleanup statement.
durationMs ?? 0 makes assertion trivially pass even when null
domains/utility/src/utility-contract-overview/__tests__/utility-contract-overview.reconcile.integration.test.ts:209
Use expect(run!.durationMs).not.toBeNull() + expect(run!.durationMs).toBeGreaterThanOrEqual(0).
Converged run doesn't assert driftCount=0/repairedCount=0 on audit row
domains/utility/src/utility-contract-overview/__tests__/utility-contract-overview.reconcile.integration.test.ts:270
Add expect(run!.driftCount).toBe(0) and expect(run!.repairedCount).toBe(0) to complete the convergence contract.
improvement3
Module-level mutable cleanup array should be scoped to describe block
domains/utility/src/utility-contract-overview/__tests__/utility-contract-overview.reconcile.integration.test.ts
createdRunIds at module scope is a shared mutation risk.
Array.from(result as Iterable<ReconcileRow>) is unnecessarily indirect
domains/utility/src/utility-contract-overview/utility-contract-overview.queries.ts
Destructuring from result.rows is cleaner than casting to Iterable.
Credential-redaction sed expression duplicated twice in workflow
.github/workflows/uco-drift-watchdog.yml:66
Extract into a reusable shell function or composite step.
History · 8 commits
- df474d4needs attentionincremental2H · 3M · 6L2026-07-22 23:12
- 8b749afneeds attentionincremental0H · 1M · 3L2026-07-14 17:58
- 8f01e3bsafeincremental0H · 0M · 0L2026-07-07 16:58
- 6fb3b0aneeds attentionincremental0H · 1M · 3L2026-07-06 16:26
- b7dc960needs attentionincremental0H · 1M · 4L2026-07-04 02:25
- c0927dfneeds attentionincremental0H · 2M · 3L2026-07-03 06:34
- 1328ef5needs attentionincremental1H · 4M · 5L2026-07-03 06:26current
- 4c3d40dneeds attentionfull6H · 15M · 12L2026-07-03 06:05