feat(greenfield): consolidate Phase 5 operational parity - #419
Conversation
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (6)
🚧 Files skipped from review as they are similar to previous changes (3)
📜 Recent review details⏰ Context from checks skipped due to timeout. (3)
🧰 Additional context used🧠 Learnings (2)📚 Learning: 2026-08-07T17:05:36.638ZApplied to files:
📚 Learning: 2026-08-07T18:47:49.639ZApplied to files:
🔇 Additional comments (3)
📝 WalkthroughSummary by CodeRabbit
WalkthroughThe change adds cache heartbeat schema v4, bounded OpenClaw cron refresh, consolidated session-only health diagnostics, and a worker-owned Moltbook dashboard with cached procedures, browser views, configuration, and deployment wiring. ChangesGreenfield platform
Estimated code review effort: 5 (Critical) | ~120 minutes Possibly related PRs
Suggested labels: 🚥 Pre-merge checks | ✅ 4✅ Passed checks (4 passed)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Codecov Report❌ Patch coverage is 📢 Thoughts on this report? Let us know! |
There was a problem hiding this comment.
Actionable comments posted: 9
🧹 Nitpick comments (18)
greenfield/src/browser/moltbook/moltbookQueries.ts (1)
6-6: 🚀 Performance & Scalability | 🔵 Trivial | 💤 Low valueConsider aligning the poll interval with the worker refresh cadence.
moltbookPollingIntervalMsis 60 seconds and applies to four queries. The worker refreshesmoltbook.dashboardevery 30 minutes (greenfield/src/server/domains/jobs/actionRegistry.tsLine 304). Each open tab therefore issues about 240 requests per hour to read data that changes twice per hour. React Query pauses polling in background tabs by default, so the cost is bounded, but a longer interval would still cut most of the traffic.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@greenfield/src/browser/moltbook/moltbookQueries.ts` at line 6, Update moltbookPollingIntervalMs to align more closely with the 30-minute moltbook.dashboard worker refresh cadence, reducing redundant polling across the four queries while preserving the existing polling behavior and query configuration.greenfield/src/server/domains/jobs/actionExecutors.ts (1)
186-255: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚖️ Poor tradeoffConsider extracting the shared cache-refresh executor shape.
createMoltbookDashboardExecutorduplicates the whole body ofcreateSystemHostExecutor(Lines 124-184). Only the cache key,failureCode,failureMessage,schemaId,source,ttlMs, and the collect call differ. A shared factory would keep the timing, failure-commit, and success-commit logic in one place, so future changes to attempt accounting apply to both jobs.♻️ Sketch of a shared factory
interface CacheRefreshExecutorSpec { readonly collect: (signal: AbortSignal) => Promise<unknown>; readonly failureCode: string; readonly failureMessage: string; readonly key: string; readonly metadata: Readonly<Record<string, string>>; readonly monotonicNowMs: () => number; readonly schemaId: string; readonly source: string; readonly ttlMs: number; } function createCacheRefreshExecutor(spec: CacheRefreshExecutorSpec): JobActionExecutor { // existing suspend/collect/commit body, parameterised by `spec` }🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@greenfield/src/server/domains/jobs/actionExecutors.ts` around lines 186 - 255, Extract the duplicated refresh flow from createSystemHostExecutor and createMoltbookDashboardExecutor into a shared createCacheRefreshExecutor factory. Parameterize the collector, failure details, cache key, metadata, schemaId, source, ttlMs, and monotonicNowMs through a CacheRefreshExecutorSpec, while preserving the existing timing, failure commit, success commit, payload validation, and completion behavior. Update both executors to provide their job-specific values to the shared factory.greenfield/src/browser/moltbook/MoltbookRoute.tsx (1)
119-119: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winReplace the non-null assertions with an explicit narrowing guard.
completeis derived fromObject.values(data), so TypeScript cannot narrowdata.home,data.feed,data.profile, ordata.ownContent. The ready branch then needs!at Lines 163, 164, 165, 167, 168, 200, 211, 232, and 247. An explicit check narrows each value, so a later change to the query set produces a compile error instead of a runtimeundefinedread.♻️ Proposed narrowing
- const complete = Object.values(data).every((value) => value !== undefined); + const ready = + data.home !== undefined && + data.feed !== undefined && + data.profile !== undefined && + data.ownContent !== undefined + ? { + feed: data.feed, + home: data.home, + ownContent: data.ownContent, + profile: data.profile, + } + : undefined; + const complete = ready !== undefined;Then read from
readyinside the ready branch and drop every!.Also applies to: 160-168
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@greenfield/src/browser/moltbook/MoltbookRoute.tsx` at line 119, Replace the Object.values-based complete check in MoltbookRoute with an explicit guard that verifies data.home, data.feed, data.profile, and data.ownContent are all defined and narrows them into a ready value. Use that narrowed ready object throughout the ready branch, including the referenced data accesses, and remove the non-null assertions.greenfield/src/server/domains/moltbook/provider.ts (1)
196-212: 🩺 Stability & Availability | 🔵 Trivial | 💤 Low valueCancel the body when the read loop aborts.
signal.throwIfAborted()and the size guard exit the loop through thefinallyblock, which only callsreader.releaseLock(). The stream stays open until the fetch signal tears it down. Callreader.cancel(...)on the abort path, as the size guard already does.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@greenfield/src/server/domains/moltbook/provider.ts` around lines 196 - 212, Update the read loop around signal.throwIfAborted() so an abort cancels the response reader before its lock is released. Preserve the existing size-limit cancellation, and ensure the abort path uses reader.cancel(...) before the finally block’s reader.releaseLock().greenfield/src/server/domains/moltbook/procedures.test.ts (1)
86-111: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winAdd coverage for the schema-mismatch guard.
readSnapshotingreenfield/src/server/domains/moltbook/routes.tsalso rejects an entry whenentry.schemaId !== "moltbook.dashboard.v1"or when the payload fails Valibot validation. These branches protect the browser from a stale or migrated cache shape. Add one case that returns an entry with an oldschemaIdand assertsSERVICE_UNAVAILABLE.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@greenfield/src/server/domains/moltbook/procedures.test.ts` around lines 86 - 111, Extend the test in “requires a cache-capable browser session and sanitizes missing state” with a cache entry using an outdated schemaId, then assert that the relevant Moltbook procedure returns SERVICE_UNAVAILABLE. Reuse the existing createTestCacheService and session-authentication setup, targeting readSnapshot’s schema-mismatch guard without changing the existing missing-state coverage.greenfield/src/server/domains/moltbook/routes.ts (1)
67-99: 🚀 Performance & Scalability | 🔵 Trivial | 💤 Low valueFour procedures read and validate the same cache row per page load.
MoltbookRoute.tsxissueshome,feed,profile, andlistMyPoststogether. Each call runsreadSnapshot, which performs one cache read plus two Valibot parses of the full snapshot. The dashboard therefore parses the same payload four times per render cycle. Consider onesnapshotprocedure that returns the projections together, or memoize the parsed entry per request context.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@greenfield/src/server/domains/moltbook/routes.ts` around lines 67 - 99, Consolidate the repeated readSnapshot work used by moltbookRoutes into a single snapshot procedure that returns the home, feed, profile, and myContent projections with status, or memoize the parsed snapshot within the request context so the four existing procedures share one cache read and validation. Preserve each procedure’s current response shape and feed sorting behavior.greenfield/src/browser/moltbook/moltbookPresentation.ts (1)
25-27: 🩺 Stability & Availability | 🔵 Trivial | 💤 Low valueGuard
formatMoltbookTimeagainst invalid timestamps.
formatDistanceToNowthrowsRangeErrorfor an invalidDate. A non-finite or out-of-rangetimestampMscan break the card tree instead of one field. The Moltbook contract validates timestamps today, so this is a defensive, optional measure.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@greenfield/src/browser/moltbook/moltbookPresentation.ts` around lines 25 - 27, Update formatMoltbookTime to validate timestampMs and the resulting Date before calling formatDistanceToNow, returning a safe fallback string for non-finite or out-of-range timestamps while preserving the existing relative-time output for valid timestamps.greenfield/src/server/domains/openClawCron/service.ts (1)
769-789: 🩺 Stability & Availability | 🔵 Trivial | 💤 Low valueConsider converting the re-entrant wait into a loop.
Line 774 calls
refreshHeartbeatProjectionrecursively after the active flight settles. Each waiting caller adds one stack frame per retry round. When a mutation invalidates the in-flight candidate, the awakened caller passes the TTL gate and starts a new flight, so a caller can recurse more than once under sustained mutation traffic. Awhileloop removes the unbounded stack growth without changing the observable single-flight behavior.♻️ Proposed loop form
- async function refreshHeartbeatProjection(): Promise<void> { - if (heartbeatDisposed) return; - const active = heartbeatRefreshPromise; - if (active !== undefined) { - await active; - await refreshHeartbeatProjection(); - return; - } + async function refreshHeartbeatProjection(): Promise<void> { + for (;;) { + if (heartbeatDisposed) return; + const active = heartbeatRefreshPromise; + if (active === undefined) break; + await active; + }The remainder of the function body stays unchanged.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@greenfield/src/server/domains/openClawCron/service.ts` around lines 769 - 789, Convert the re-entrant retry in refreshHeartbeatProjection into a while loop: continue waiting for heartbeatRefreshPromise and retry the projection within the same invocation instead of recursively calling refreshHeartbeatProjection after the active flight settles. Preserve the existing disposed, monotonic-time, TTL-gate, and single-flight behavior for all other paths.greenfield/src/server/domains/cache/heartbeatProjection.test.ts (1)
150-167: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low valueThe
taskReadOpenassertion cannot fail.The
finallyblock setstaskReadOpento false beforereadSnapshotreturns.expect(taskReadOpen).toBeFalse()at Line 161 therefore passes even ifrefreshCronwere called inside the read. Theeventsarray already proves the ordering. Remove the flag, or set it to false only after the call returns.♻️ Proposed simplification
- let taskReadOpen = false; const events: string[] = []; const snapshot = { rows: [], totalCount: 0, }; const available = await readCacheHeartbeatTasksWithCronRefresh( () => { events.push("task-read"); - taskReadOpen = true; - try { - return snapshot; - } finally { - taskReadOpen = false; - } + return snapshot; }, () => { - expect(taskReadOpen).toBeFalse(); events.push("cron-refresh"); return Promise.resolve(); },🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@greenfield/src/server/domains/cache/heartbeatProjection.test.ts` around lines 150 - 167, Remove the ineffective taskReadOpen flag and its assertion from the readCacheHeartbeatTasksWithCronRefresh test; retain the events ordering assertion as the verification that cron refresh occurs after the task read.greenfield/src/contracts/cache.test.ts (1)
541-584: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winAdd negative coverage for the last-known-good relaxation.
The test covers only the permissive last-known-good paths. The relaxation in
cacheHeartbeatCronProjectionIsConsistentstill rejects two cases:expectedPendingSync === "present"withpendingSync !== "present", andexpectedPendingSync === "unknown"withpendingSync === "none". Add both cases so a future simplification of that branch fails the test.♻️ Proposed additional assertions
expect( cacheHeartbeatCronProjectionIsConsistent({ count: 1, health, observedAtMs: 1000, pendingSync: "present", state: "fresh", }) ).toBeFalse(); + expect( + cacheHeartbeatCronProjectionIsConsistent({ + count: 1, + health: { ...health, synchronizationPendingCount: 1 }, + observedAtMs: 1000, + pendingSync: "unknown", + staleSinceMs: 1100, + state: "last-known-good", + }) + ).toBeFalse(); + expect( + cacheHeartbeatCronProjectionIsConsistent({ + count: 2, + health: { ...health, truncated: true }, + observedAtMs: 1000, + pendingSync: "none", + staleSinceMs: 1100, + state: "last-known-good", + }) + ).toBeFalse(); + });🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@greenfield/src/contracts/cache.test.ts` around lines 541 - 584, Extend the test “allows last-known-good synchronization warnings to strengthen stale counts” with negative assertions for last-known-good projections: reject expectedPendingSync "present" when pendingSync is not "present", and reject expectedPendingSync "unknown" when pendingSync is "none". Keep the existing permissive cases unchanged and assert both results are false.greenfield/src/contracts/cache.ts (1)
555-563: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low valueAdd parentheses to the truncation equality.
projection.health.truncated === projection.health.inspectedCount < projection.countrelies on relational precedence binding before equality. The behavior is correct, but the formatted line reads as an ambiguous chain. Explicit parentheses remove the ambiguity. The same pattern appears at Line 753.♻️ Proposed clarification
return ( projection.health.inspectedCount <= projection.count && - projection.health.truncated === - projection.health.inspectedCount < projection.count + projection.health.truncated === + (projection.health.inspectedCount < projection.count) );🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@greenfield/src/contracts/cache.ts` around lines 555 - 563, In cacheHeartbeatCronHealthIsConsistent, parenthesize the relational expression comparing projection.health.inspectedCount with projection.count before applying the truncation equality. Apply the same explicit-parentheses change to the matching truncation comparison at the other occurrence around line 753.greenfield/src/server/domains/system/healthDiagnosticsService.ts (1)
199-226: 🩺 Stability & Availability | 🔵 Trivial | ⚡ Quick winGuard
readiness.isReady()like every other reader.Each dependency read is wrapped and degrades to an explicit unavailable state.
dependencies.readiness.isReady()is not wrapped. If a readiness implementation throws,read()throws and the session procedure returns an internal error instead of a diagnostics snapshot. The test inhealthDiagnosticsService.test.tsnames a fixturethrowingReadiness, but that fixture does not throw, so this path is untested.♻️ Proposed guard
+function readApplicationStatus(readiness: ReadinessState): "not-ready" | "ready" { + try { + return readiness.isReady() ? "ready" : "not-ready"; + } catch { + return "not-ready"; + } +}const checks = { application: { - status: dependencies.readiness.isReady() - ? ("ready" as const) - : ("not-ready" as const), + status: readApplicationStatus(dependencies.readiness), },🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@greenfield/src/server/domains/system/healthDiagnosticsService.ts` around lines 199 - 226, Wrap the readiness check in the health diagnostics `checks` construction with the same error guard used by the other dependency readers, mapping any exception from `dependencies.readiness.isReady()` to an explicit unavailable status while preserving ready/not-ready results for successful reads. Update the `throwingReadiness` fixture in `healthDiagnosticsService.test.ts` to actually throw so the guarded path is covered.greenfield/src/server/domains/cache/service.test.ts (1)
437-452: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low valueLabel each malformed fixture so failures identify the case.
Both loops assert eight anonymous fixtures. If one iteration fails, the report does not show which shape failed. Add a
labelto each fixture and pass it to the assertion context, or wrap each iteration intest.each.♻️ Example for the dashboard-job loop
- for (const dashboardJobs of malformedDashboardJobProjections) { + for (const [index, dashboardJobs] of malformedDashboardJobProjections.entries()) { const service = createCacheService({ cacheRepository: readOnlyCacheRepository(record), jobRepository: Object.freeze({}) as never, nowMs: () => 7000, readHeartbeatDashboardJobs: () => ({ dashboardJobs, generatedAtMs: 7000, }) as never, readHeartbeatTasks: () => validTasks, }); - expect(await Effect.runPromise(service.getHeartbeat())).toMatchObject({ + const heartbeat = await Effect.runPromise(service.getHeartbeat()); + expect(heartbeat, `malformed dashboard-job projection ${index}`).toMatchObject({ dashboardJobs: { state: "unavailable" }, tasks: { items: [], state: "available" }, }); }Also applies to: 599-615
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@greenfield/src/server/domains/cache/service.test.ts` around lines 437 - 452, Label every fixture in both malformedTaskProjections and malformed dashboard-job projection loops, then include each fixture’s label in the assertion context or convert the loops to test.each so a failure identifies the malformed shape. Preserve the existing heartbeat expectations and service setup.greenfield/src/server/domains/tasks/repositoryTypes.ts (1)
63-74: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low valueNarrow
assigneeto its non-null form.If
TaskRecord["assignee"]includesnull, thenassignee?: TaskRecord["assignee"]acceptsstring | null | undefined.readHeartbeatCandidatesomits the property when the column is null, so the null case never occurs. Consumers still must handle it. UseNonNullable<TaskRecord["assignee"]>to encode the reader guarantee.♻️ Proposed change
export interface TaskHeartbeatCandidateRecord { - readonly assignee?: TaskRecord["assignee"]; + readonly assignee?: NonNullable<TaskRecord["assignee"]>;🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@greenfield/src/server/domains/tasks/repositoryTypes.ts` around lines 63 - 74, Update TaskHeartbeatCandidateRecord.assignee to use NonNullable<TaskRecord["assignee"]> while retaining optional-property semantics, so its type represents only string-or-undefined and matches readHeartbeatCandidates omitting null values.greenfield/src/contracts/system.ts (1)
182-192: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low valueBound
freshCountandcapacityexplicitly.
systemHealthDiagnosticsCountSchemahas no upper bound, sofreshCountaccepts any safe integer. The capacity rule then derives its ceiling from that unbounded value. TheNumber.isSafeInteger(maximumCapacity)guard prevents overflow, but the projection stays unbounded. Other projections in this file apply an explicit budget, for examplegatewaySessionProjectionMaximumon the session count. Consider applying a worker-count budget for the same reason.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@greenfield/src/contracts/system.ts` around lines 182 - 192, Update systemHealthDiagnosticsWorkersAreConsistent to enforce an explicit worker-count budget on freshCount and capacity, using the file’s established worker maximum or projection-budget symbol. Ensure freshCount does not exceed that budget and capacity is validated against the same bounded range, rather than relying only on Number.isSafeInteger(maximumCapacity).greenfield/src/server/domains/tasks/repositoryReader.ts (1)
264-274: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winMove the heartbeat relevance policy out of the persistence reader.
The assignee names
"mira-2026"and"rajohan", the priority set, and the blocked-status rule are product policy, not persistence detail. Placing them in the Drizzle reader couples the storage layer to the policy and hides the rule from the domain and contract layers, where the heartbeat projection is defined. Export these values from a shared module and import them here, so a policy change has one edit site.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@greenfield/src/server/domains/tasks/repositoryReader.ts` around lines 264 - 274, Move the heartbeat relevance policy constants for the assignee names, priority set, and blocked-status rule out of the persistence reader into a shared domain/contract module, export them there, and import them into the relevance expression in the reader. Preserve the existing linkedAutomation and non-done filtering while ensuring policy changes have a single definition site.greenfield/src/server/domains/jobs/repository.test.ts (1)
2275-2291: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚖️ Poor tradeoffThe plan assertions test hand-written SQL, not the repository query.
queuedPlanandworkerPlanrun literal SQL strings that duplicate the shape of thereadHealthStatequeries. IfreadHealthStatechanges its predicates or its aggregate columns, these assertions still pass and the index regression stays undetected. Consider asserting the plan of the query the repository builds, for example through the Drizzle query builder's SQL output, so the two stay coupled.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@greenfield/src/server/domains/jobs/repository.test.ts` around lines 2275 - 2291, Update the query-plan assertions near readHealthState to inspect the SQL generated by the repository’s actual Drizzle query builder instead of hand-written SQL duplicates. Ensure queuedPlan and workerPlan derive from the same query definitions and parameters used by readHealthState, while preserving the existing index and temporary B-tree assertions.greenfield/src/contracts/system.test.ts (1)
104-243: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winAdd coverage for the
last-known-goodsession branch.The tests exercise the
freshsession variant only. The schema also acceptslast-known-goodwithstaleSinceMs, andsystemHealthDiagnosticsSessionsAreConsistentgatesstaleSinceMs >= observedAtMs. No test covers that ordering rule or the aggregate rulestaleSinceMs <= checkedAtMs. Add two cases so a future change to the ordering comparison fails the suite.Also consider splitting this single test into per-rule tests. The current test asserts thirteen rejection paths, so a failure message does not identify the failing rule.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@greenfield/src/contracts/system.test.ts` around lines 104 - 243, Extend coverage around systemHealthDiagnosticsSessionsAreConsistent for the last-known-good session variant: add one rejection case where staleSinceMs is earlier than observedAtMs and another where it exceeds checkedAtMs, asserting the appropriate validation errors. Split the oversized “rejects inconsistent aggregate and worker states” test into focused per-rule tests so failures identify the violated projection or ordering rule.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@greenfield/src/browser/layout/DashboardShell.tsx`:
- Line 51: Update the Moltbook navigation entry in DashboardShell to use a
distinct icon instead of Bot, adding BookOpen to the existing lucide-react
import and assigning it to the “Moltbook” item while leaving the Agents icon
unchanged.
In `@greenfield/src/browser/layout/dashboardSystemStatus.test.ts`:
- Around line 47-88: Add the missing assertion in the test named “marks only
retained snapshots without a current observation stale” for an idle fetch with
data, no error, and isStale false, and verify dashboardHealthSnapshotIsStale
returns false.
In `@greenfield/src/browser/layout/dashboardSystemStatus.ts`:
- Around line 93-107: Update workerState so queue.claimingPaused does not map a
ready worker to "offline"; use the intended weaker non-offline state while
preserving "unavailable" handling and normal "online" behavior when claiming is
active. Verify the resulting overallSystemState does not escalate an intentional
claiming pause to "offline".
In `@greenfield/src/browser/moltbook/MoltbookCards.tsx`:
- Around line 159-161: Update the vote counter markup in MoltbookOwnPostCard and
the corresponding pattern around the later vote display so the upvote and
downvote glyphs are hidden from assistive technology and each count has an
accessible text label conveying its meaning. Preserve the existing visual
arrows, counts, and surrounding comment text.
In `@greenfield/src/browser/moltbook/moltbookPresentation.ts`:
- Around line 29-33: Update truncateMoltbookText to truncate by Unicode code
points rather than UTF-16 code units, ensuring the result never splits an emoji
or other surrogate pair while preserving the maximumCharacters limit and
existing ellipsis behavior.
In `@greenfield/src/browser/moltbook/MoltbookRoute.tsx`:
- Around line 146-160: Update moltbookFeedQueryOptions so changing sort retains
the previous feed as placeholder data while the new query loads, instead of
exposing undefined data. Ensure MoltbookRoute’s loading/complete state continues
rendering the existing ready branch and Tabs during refetch, using the
fetch-in-progress state only for retry or background-loading indicators.
In `@greenfield/src/server/domains/cache/heartbeatProjection.ts`:
- Around line 118-130: Update readCacheHeartbeatDashboardJobs and its
projectActiveRun flow so terminal active-run rows or repository.findSchedule
errors degrade the affected dashboard job to the existing { state: "unavailable"
} result instead of propagating and failing the entire heartbeat response.
Preserve normal projections for queued or running runs and the existing
degradation behavior for other read failures.
In `@greenfield/src/server/domains/jobs/repository.test.ts`:
- Around line 2229-2264: Update the queued-run setup around queuedRun(20) and
queuedRun(21) so the test explicitly enqueues exactly one queued run, either by
removing the active run iteration or by asserting queuedRun(21)'s active result
directly. Preserve the existing aggregate expectations for the single queued
run.
In `@greenfield/src/server/domains/moltbook/provider.ts`:
- Around line 475-490: Update the snapshot-building flow around the two v.parse
calls so schema validation failures are explicitly converted to
MoltbookProviderFailure("invalid-response") before reaching normalizeFailure.
Keep the cacheEntryPayloadSchema row-budget breach classified as "unavailable",
separating that validation from the dashboard snapshot schema validation, and
preserve the existing failure handling for other errors.
---
Nitpick comments:
In `@greenfield/src/browser/moltbook/moltbookPresentation.ts`:
- Around line 25-27: Update formatMoltbookTime to validate timestampMs and the
resulting Date before calling formatDistanceToNow, returning a safe fallback
string for non-finite or out-of-range timestamps while preserving the existing
relative-time output for valid timestamps.
In `@greenfield/src/browser/moltbook/moltbookQueries.ts`:
- Line 6: Update moltbookPollingIntervalMs to align more closely with the
30-minute moltbook.dashboard worker refresh cadence, reducing redundant polling
across the four queries while preserving the existing polling behavior and query
configuration.
In `@greenfield/src/browser/moltbook/MoltbookRoute.tsx`:
- Line 119: Replace the Object.values-based complete check in MoltbookRoute with
an explicit guard that verifies data.home, data.feed, data.profile, and
data.ownContent are all defined and narrows them into a ready value. Use that
narrowed ready object throughout the ready branch, including the referenced data
accesses, and remove the non-null assertions.
In `@greenfield/src/contracts/cache.test.ts`:
- Around line 541-584: Extend the test “allows last-known-good synchronization
warnings to strengthen stale counts” with negative assertions for
last-known-good projections: reject expectedPendingSync "present" when
pendingSync is not "present", and reject expectedPendingSync "unknown" when
pendingSync is "none". Keep the existing permissive cases unchanged and assert
both results are false.
In `@greenfield/src/contracts/cache.ts`:
- Around line 555-563: In cacheHeartbeatCronHealthIsConsistent, parenthesize the
relational expression comparing projection.health.inspectedCount with
projection.count before applying the truncation equality. Apply the same
explicit-parentheses change to the matching truncation comparison at the other
occurrence around line 753.
In `@greenfield/src/contracts/system.test.ts`:
- Around line 104-243: Extend coverage around
systemHealthDiagnosticsSessionsAreConsistent for the last-known-good session
variant: add one rejection case where staleSinceMs is earlier than observedAtMs
and another where it exceeds checkedAtMs, asserting the appropriate validation
errors. Split the oversized “rejects inconsistent aggregate and worker states”
test into focused per-rule tests so failures identify the violated projection or
ordering rule.
In `@greenfield/src/contracts/system.ts`:
- Around line 182-192: Update systemHealthDiagnosticsWorkersAreConsistent to
enforce an explicit worker-count budget on freshCount and capacity, using the
file’s established worker maximum or projection-budget symbol. Ensure freshCount
does not exceed that budget and capacity is validated against the same bounded
range, rather than relying only on Number.isSafeInteger(maximumCapacity).
In `@greenfield/src/server/domains/cache/heartbeatProjection.test.ts`:
- Around line 150-167: Remove the ineffective taskReadOpen flag and its
assertion from the readCacheHeartbeatTasksWithCronRefresh test; retain the
events ordering assertion as the verification that cron refresh occurs after the
task read.
In `@greenfield/src/server/domains/cache/service.test.ts`:
- Around line 437-452: Label every fixture in both malformedTaskProjections and
malformed dashboard-job projection loops, then include each fixture’s label in
the assertion context or convert the loops to test.each so a failure identifies
the malformed shape. Preserve the existing heartbeat expectations and service
setup.
In `@greenfield/src/server/domains/jobs/actionExecutors.ts`:
- Around line 186-255: Extract the duplicated refresh flow from
createSystemHostExecutor and createMoltbookDashboardExecutor into a shared
createCacheRefreshExecutor factory. Parameterize the collector, failure details,
cache key, metadata, schemaId, source, ttlMs, and monotonicNowMs through a
CacheRefreshExecutorSpec, while preserving the existing timing, failure commit,
success commit, payload validation, and completion behavior. Update both
executors to provide their job-specific values to the shared factory.
In `@greenfield/src/server/domains/jobs/repository.test.ts`:
- Around line 2275-2291: Update the query-plan assertions near readHealthState
to inspect the SQL generated by the repository’s actual Drizzle query builder
instead of hand-written SQL duplicates. Ensure queuedPlan and workerPlan derive
from the same query definitions and parameters used by readHealthState, while
preserving the existing index and temporary B-tree assertions.
In `@greenfield/src/server/domains/moltbook/procedures.test.ts`:
- Around line 86-111: Extend the test in “requires a cache-capable browser
session and sanitizes missing state” with a cache entry using an outdated
schemaId, then assert that the relevant Moltbook procedure returns
SERVICE_UNAVAILABLE. Reuse the existing createTestCacheService and
session-authentication setup, targeting readSnapshot’s schema-mismatch guard
without changing the existing missing-state coverage.
In `@greenfield/src/server/domains/moltbook/provider.ts`:
- Around line 196-212: Update the read loop around signal.throwIfAborted() so an
abort cancels the response reader before its lock is released. Preserve the
existing size-limit cancellation, and ensure the abort path uses
reader.cancel(...) before the finally block’s reader.releaseLock().
In `@greenfield/src/server/domains/moltbook/routes.ts`:
- Around line 67-99: Consolidate the repeated readSnapshot work used by
moltbookRoutes into a single snapshot procedure that returns the home, feed,
profile, and myContent projections with status, or memoize the parsed snapshot
within the request context so the four existing procedures share one cache read
and validation. Preserve each procedure’s current response shape and feed
sorting behavior.
In `@greenfield/src/server/domains/openClawCron/service.ts`:
- Around line 769-789: Convert the re-entrant retry in
refreshHeartbeatProjection into a while loop: continue waiting for
heartbeatRefreshPromise and retry the projection within the same invocation
instead of recursively calling refreshHeartbeatProjection after the active
flight settles. Preserve the existing disposed, monotonic-time, TTL-gate, and
single-flight behavior for all other paths.
In `@greenfield/src/server/domains/system/healthDiagnosticsService.ts`:
- Around line 199-226: Wrap the readiness check in the health diagnostics
`checks` construction with the same error guard used by the other dependency
readers, mapping any exception from `dependencies.readiness.isReady()` to an
explicit unavailable status while preserving ready/not-ready results for
successful reads. Update the `throwingReadiness` fixture in
`healthDiagnosticsService.test.ts` to actually throw so the guarded path is
covered.
In `@greenfield/src/server/domains/tasks/repositoryReader.ts`:
- Around line 264-274: Move the heartbeat relevance policy constants for the
assignee names, priority set, and blocked-status rule out of the persistence
reader into a shared domain/contract module, export them there, and import them
into the relevance expression in the reader. Preserve the existing
linkedAutomation and non-done filtering while ensuring policy changes have a
single definition site.
In `@greenfield/src/server/domains/tasks/repositoryTypes.ts`:
- Around line 63-74: Update TaskHeartbeatCandidateRecord.assignee to use
NonNullable<TaskRecord["assignee"]> while retaining optional-property semantics,
so its type represents only string-or-undefined and matches
readHeartbeatCandidates omitting null values.
🪄 Autofix
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro Plus
Run ID: 4ce4dd66-fdaf-488a-a4da-acfae2a68c43
⛔ Files ignored due to path filters (12)
greenfield/docs/generated/configuration.mdis excluded by!**/generated/**and included by**/*greenfield/docs/generated/procedures.mdis excluded by!**/generated/**and included by**/*greenfield/docs/generated/routes-and-features.mdis excluded by!**/generated/**and included by**/*greenfield/docs/generated/schemas/cache.getHeartbeat.output.schema.jsonis excluded by!**/generated/**and included by**/*greenfield/docs/generated/schemas/moltbook.feed.input.v1.schema.jsonis excluded by!**/generated/**and included by**/*greenfield/docs/generated/schemas/moltbook.feed.result.v1.schema.jsonis excluded by!**/generated/**and included by**/*greenfield/docs/generated/schemas/moltbook.home.result.v1.schema.jsonis excluded by!**/generated/**and included by**/*greenfield/docs/generated/schemas/moltbook.own-content.result.v1.schema.jsonis excluded by!**/generated/**and included by**/*greenfield/docs/generated/schemas/moltbook.profile.result.v1.schema.jsonis excluded by!**/generated/**and included by**/*greenfield/docs/generated/schemas/system.empty.v1.schema.jsonis excluded by!**/generated/**and included by**/*greenfield/docs/generated/schemas/system.healthDiagnostics.input.schema.jsonis excluded by!**/generated/**and included by**/*greenfield/docs/generated/schemas/system.healthDiagnostics.output.schema.jsonis excluded by!**/generated/**and included by**/*
📒 Files selected for processing (97)
greenfield/docs/architecture/greenfield-rewrite/application-architecture.mdgreenfield/docs/architecture/greenfield-rewrite/data-and-security.mdgreenfield/docs/architecture/greenfield-rewrite/implementation-plan.mdgreenfield/docs/architecture/greenfield-rewrite/progress.mdgreenfield/package.jsongreenfield/scripts/delivery/systemdProductionServices.test.tsgreenfield/scripts/development/developmentEnvironment.tsgreenfield/scripts/documentation/artifacts.test.tsgreenfield/scripts/documentation/jsonSchema.test.tsgreenfield/scripts/documentation/jsonSchema.tsgreenfield/scripts/frontendBuildArtifacts.tsgreenfield/scripts/sourceBoundaries/policy.test.tsgreenfield/scripts/sourceBoundaries/sourceTopologyPolicy.tsgreenfield/src/app/dashboardServer.test.tsgreenfield/src/app/dashboardServer.tsgreenfield/src/app/dashboardServerProcess.test.tsgreenfield/src/app/developmentWorker.tsgreenfield/src/app/server.tsgreenfield/src/app/trpcHttpHandler.tsgreenfield/src/app/worker.test.tsgreenfield/src/app/worker.tsgreenfield/src/browser/api/trpcClient.tsgreenfield/src/browser/application.test.tsxgreenfield/src/browser/layout/DashboardHeaderControls.tsxgreenfield/src/browser/layout/DashboardShell.tsxgreenfield/src/browser/layout/dashboardSystemStatus.test.tsgreenfield/src/browser/layout/dashboardSystemStatus.tsgreenfield/src/browser/moltbook/MoltbookCards.tsxgreenfield/src/browser/moltbook/MoltbookRoute.test.tsxgreenfield/src/browser/moltbook/MoltbookRoute.tsxgreenfield/src/browser/moltbook/moltbookPresentation.tsgreenfield/src/browser/moltbook/moltbookQueries.tsgreenfield/src/browser/router.tsxgreenfield/src/browser/routes/moltbook.lazy.tsxgreenfield/src/contracts/cache.test.tsgreenfield/src/contracts/cache.tsgreenfield/src/contracts/contractRegistry.tsgreenfield/src/contracts/jobLimits.tsgreenfield/src/contracts/jobModel.tsgreenfield/src/contracts/moltbook.test.tsgreenfield/src/contracts/moltbook.tsgreenfield/src/contracts/system.test.tsgreenfield/src/contracts/system.tsgreenfield/src/server/domains/cache/heartbeatProjection.test.tsgreenfield/src/server/domains/cache/heartbeatProjection.tsgreenfield/src/server/domains/cache/procedures.test.tsgreenfield/src/server/domains/cache/providerRegistry.tsgreenfield/src/server/domains/cache/service.test.tsgreenfield/src/server/domains/cache/service.tsgreenfield/src/server/domains/jobs/actionExecutors.test.tsgreenfield/src/server/domains/jobs/actionExecutors.tsgreenfield/src/server/domains/jobs/actionRegistry.tsgreenfield/src/server/domains/jobs/coordinator.test.tsgreenfield/src/server/domains/jobs/repository.test.tsgreenfield/src/server/domains/jobs/repository.tsgreenfield/src/server/domains/jobs/workerRuntime.test.tsgreenfield/src/server/domains/jobs/workerRuntime.tsgreenfield/src/server/domains/jobs/workerSystem.test.tsgreenfield/src/server/domains/moltbook/procedures.test.tsgreenfield/src/server/domains/moltbook/procedures.tsgreenfield/src/server/domains/moltbook/provider.test.tsgreenfield/src/server/domains/moltbook/provider.tsgreenfield/src/server/domains/moltbook/routes.tsgreenfield/src/server/domains/openClawCron/projection.tsgreenfield/src/server/domains/openClawCron/provider.tsgreenfield/src/server/domains/openClawCron/service.test.tsgreenfield/src/server/domains/openClawCron/service.tsgreenfield/src/server/domains/system/healthDiagnosticsService.test.tsgreenfield/src/server/domains/system/healthDiagnosticsService.tsgreenfield/src/server/domains/system/procedures.test.tsgreenfield/src/server/domains/system/procedures.tsgreenfield/src/server/domains/tasks/repository.tsgreenfield/src/server/domains/tasks/repositoryReader.test.tsgreenfield/src/server/domains/tasks/repositoryReader.tsgreenfield/src/server/domains/tasks/repositoryTypes.tsgreenfield/src/server/platform/configuration/configurationRegistry.test.tsgreenfield/src/server/platform/configuration/moltbookConfiguration.tsgreenfield/src/server/platform/configuration/workerConfiguration.test.tsgreenfield/src/server/platform/configuration/workerConfiguration.tsgreenfield/src/server/platform/gateway/persistentGatewayTransport.test.tsgreenfield/src/server/platform/gateway/persistentGatewayTransport.tsgreenfield/src/server/platform/gateway/persistentOpenClawCronProvider.test.tsgreenfield/src/server/platform/gateway/persistentOpenClawCronProvider.tsgreenfield/src/server/test/support/moltbook.tsgreenfield/src/server/test/support/requestContext.tsgreenfield/src/server/trpc/appRouter.tsgreenfield/src/server/trpc/context.test.tsgreenfield/src/server/trpc/context.tsgreenfield/src/server/trpc/procedureErrorPolicy.tsgreenfield/src/shared/browserRouteRegistry.tsgreenfield/src/shared/configuration/applicationConfigurationRegistry.tsgreenfield/src/test/parity/fixtures/frontend-routes.jsongreenfield/src/test/parity/fixtures/greenfield-contracts.jsongreenfield/src/test/parity/fixtures/legacy-endpoints.jsongreenfield/src/test/parity/parityInventory.test.tsgreenfield/systemd/mira-dashboard-web.servicegreenfield/systemd/mira-dashboard-worker.service
📜 Review details
⏰ Context from checks skipped due to timeout. (3)
- GitHub Check: storybook
- GitHub Check: dashboard-checks
- GitHub Check: Analyze JavaScript and TypeScript
🧰 Additional context used
🧠 Learnings (2)
📚 Learning: 2026-08-07T18:47:49.639Z
Learnt from: mira-2026
Repo: rajohan/Mira-Dashboard PR: 398
File: greenfield/src/server/domains/monitoring/catalogErrors.ts:3-3
Timestamp: 2026-08-07T18:47:49.639Z
Learning: In the greenfield TypeScript application, use the pinned Effect version 4.0.0-beta.104 API. Preserve `Schema.Literals` for readonly literal tuples and arrays, and do not replace it with variadic `Schema.Literal(...)` unless the replacement has been validated against the pinned Effect version.
Applied to files:
greenfield/scripts/sourceBoundaries/sourceTopologyPolicy.tsgreenfield/src/server/domains/openClawCron/provider.tsgreenfield/src/contracts/jobLimits.tsgreenfield/src/browser/api/trpcClient.tsgreenfield/scripts/documentation/artifacts.test.tsgreenfield/src/server/trpc/appRouter.tsgreenfield/src/app/trpcHttpHandler.tsgreenfield/src/contracts/moltbook.test.tsgreenfield/src/contracts/contractRegistry.tsgreenfield/src/server/domains/jobs/workerRuntime.tsgreenfield/src/app/developmentWorker.tsgreenfield/src/server/platform/configuration/configurationRegistry.test.tsgreenfield/src/app/dashboardServerProcess.test.tsgreenfield/src/server/domains/jobs/repository.test.tsgreenfield/src/server/test/support/moltbook.tsgreenfield/src/server/domains/jobs/workerRuntime.test.tsgreenfield/scripts/development/developmentEnvironment.tsgreenfield/scripts/frontendBuildArtifacts.tsgreenfield/src/browser/moltbook/moltbookPresentation.tsgreenfield/src/test/parity/parityInventory.test.tsgreenfield/src/contracts/system.test.tsgreenfield/src/server/platform/gateway/persistentGatewayTransport.test.tsgreenfield/src/server/domains/jobs/workerSystem.test.tsgreenfield/src/server/domains/jobs/coordinator.test.tsgreenfield/scripts/documentation/jsonSchema.test.tsgreenfield/src/server/domains/moltbook/procedures.test.tsgreenfield/src/server/platform/configuration/moltbookConfiguration.tsgreenfield/src/server/domains/jobs/repository.tsgreenfield/src/server/domains/tasks/repository.tsgreenfield/src/server/domains/moltbook/provider.test.tsgreenfield/scripts/sourceBoundaries/policy.test.tsgreenfield/src/server/trpc/context.test.tsgreenfield/src/server/domains/cache/providerRegistry.tsgreenfield/src/shared/browserRouteRegistry.tsgreenfield/src/contracts/jobModel.tsgreenfield/src/app/server.tsgreenfield/src/server/domains/jobs/actionExecutors.test.tsgreenfield/src/server/domains/cache/heartbeatProjection.test.tsgreenfield/src/server/domains/tasks/repositoryReader.test.tsgreenfield/src/server/domains/tasks/repositoryReader.tsgreenfield/src/server/trpc/context.tsgreenfield/scripts/delivery/systemdProductionServices.test.tsgreenfield/src/contracts/cache.test.tsgreenfield/src/server/platform/configuration/workerConfiguration.test.tsgreenfield/src/server/domains/jobs/actionRegistry.tsgreenfield/src/app/worker.test.tsgreenfield/scripts/documentation/jsonSchema.tsgreenfield/src/server/domains/openClawCron/projection.tsgreenfield/src/server/platform/gateway/persistentOpenClawCronProvider.tsgreenfield/src/app/worker.tsgreenfield/src/server/domains/system/healthDiagnosticsService.tsgreenfield/src/server/domains/cache/heartbeatProjection.tsgreenfield/src/server/domains/cache/procedures.test.tsgreenfield/src/server/domains/moltbook/routes.tsgreenfield/src/server/domains/tasks/repositoryTypes.tsgreenfield/src/browser/moltbook/moltbookQueries.tsgreenfield/src/server/domains/moltbook/procedures.tsgreenfield/src/server/domains/system/procedures.test.tsgreenfield/src/server/domains/system/healthDiagnosticsService.test.tsgreenfield/src/server/domains/cache/service.test.tsgreenfield/src/server/domains/cache/service.tsgreenfield/src/server/test/support/requestContext.tsgreenfield/src/contracts/moltbook.tsgreenfield/src/server/platform/configuration/workerConfiguration.tsgreenfield/src/server/domains/jobs/actionExecutors.tsgreenfield/src/server/domains/system/procedures.tsgreenfield/src/shared/configuration/applicationConfigurationRegistry.tsgreenfield/src/server/platform/gateway/persistentOpenClawCronProvider.test.tsgreenfield/src/app/dashboardServer.tsgreenfield/src/contracts/system.tsgreenfield/src/server/domains/moltbook/provider.tsgreenfield/src/server/platform/gateway/persistentGatewayTransport.tsgreenfield/src/server/domains/openClawCron/service.test.tsgreenfield/src/server/domains/openClawCron/service.tsgreenfield/src/browser/layout/dashboardSystemStatus.test.tsgreenfield/src/contracts/cache.tsgreenfield/src/server/trpc/procedureErrorPolicy.tsgreenfield/src/app/dashboardServer.test.tsgreenfield/src/browser/layout/dashboardSystemStatus.ts
📚 Learning: 2026-08-07T17:05:36.638Z
Learnt from: mira-2026
Repo: rajohan/Mira-Dashboard PR: 397
File: greenfield/src/server/domains/agents/service.test.ts:225-239
Timestamp: 2026-08-07T17:05:36.638Z
Learning: In Bun test files, write rejection assertions as `expect(promise).rejects...` without `await`. The repository's installed matcher types return `void`, and ESLint's `typescript(await-thenable)` rule rejects awaiting these matcher assertions.
Applied to files:
greenfield/scripts/documentation/artifacts.test.tsgreenfield/src/contracts/moltbook.test.tsgreenfield/src/server/platform/configuration/configurationRegistry.test.tsgreenfield/src/app/dashboardServerProcess.test.tsgreenfield/src/server/domains/jobs/repository.test.tsgreenfield/src/server/domains/jobs/workerRuntime.test.tsgreenfield/src/test/parity/parityInventory.test.tsgreenfield/src/contracts/system.test.tsgreenfield/src/server/platform/gateway/persistentGatewayTransport.test.tsgreenfield/src/server/domains/jobs/workerSystem.test.tsgreenfield/src/server/domains/jobs/coordinator.test.tsgreenfield/scripts/documentation/jsonSchema.test.tsgreenfield/src/server/domains/moltbook/procedures.test.tsgreenfield/src/server/domains/moltbook/provider.test.tsgreenfield/scripts/sourceBoundaries/policy.test.tsgreenfield/src/server/trpc/context.test.tsgreenfield/src/server/domains/jobs/actionExecutors.test.tsgreenfield/src/server/domains/cache/heartbeatProjection.test.tsgreenfield/src/server/domains/tasks/repositoryReader.test.tsgreenfield/scripts/delivery/systemdProductionServices.test.tsgreenfield/src/contracts/cache.test.tsgreenfield/src/server/platform/configuration/workerConfiguration.test.tsgreenfield/src/app/worker.test.tsgreenfield/src/server/domains/cache/procedures.test.tsgreenfield/src/server/domains/system/procedures.test.tsgreenfield/src/server/domains/system/healthDiagnosticsService.test.tsgreenfield/src/server/domains/cache/service.test.tsgreenfield/src/server/platform/gateway/persistentOpenClawCronProvider.test.tsgreenfield/src/server/domains/openClawCron/service.test.tsgreenfield/src/browser/layout/dashboardSystemStatus.test.tsgreenfield/src/app/dashboardServer.test.ts
🪛 ast-grep (0.45.1)
greenfield/src/server/domains/moltbook/routes.ts
[error] 88-97: Avoid SQL injection
Context: moltbookReadProcedure
.input(emptyInputSchema)
.output(moltbookProfileResultSchema)
.query(async ({ ctx }) => {
const { snapshot, status } = await readSnapshot(ctx.cacheService);
return {
...(snapshot.profile === undefined ? {} : { profile: snapshot.profile }),
status,
};
})
Note: [CWE-89] Improper Neutralization of Special Elements used in an SQL Command ('SQL Injection').
(sql-injection-typescript)
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 13c3474b0d
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
|
@codex review |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: b37cb2e8fa
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
|
@codex review |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 068107e4cc
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
|
@codex review |
|
Codex Review: Didn't find any major issues. What shall we delve into next? Reviewed commit: ℹ️ About Codex in GitHubCodex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
If Codex has suggestions, it will comment; otherwise it will react with 👍. When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback". |
Summary
Parity status
Safety and resource bounds
Verification
No production cutover, service activation, Gateway restart, or legacy removal is included. This PR is stacked on #418.