feat(rewrite): add Phase 3 cache foundation - #403
Conversation
📝 WalkthroughSummary by CodeRabbit
WalkthroughThe PR adds a cache domain with validated contracts, durable SQLite storage, claim-fenced worker persistence, a ChangesCache domain and worker integration
Estimated code review effort: 5 (Critical) | ~120 minutes Sequence Diagram(s)sequenceDiagram
participant WorkerRuntime
participant JobCoordinator
participant SystemHostProvider
participant CacheRepository
participant RealtimeOutbox
WorkerRuntime->>JobCoordinator: execute claimed system.host job
JobCoordinator->>SystemHostProvider: collectSystemHostPayload()
SystemHostProvider-->>JobCoordinator: validated host payload
JobCoordinator->>CacheRepository: commitCacheAttempt()
CacheRepository->>RealtimeOutbox: persist cache.entries event
CacheRepository-->>JobCoordinator: committed or lost-claim
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: 2
🧹 Nitpick comments (6)
greenfield/src/server/database/schema/cacheEntries.ts (1)
36-41: 🗄️ Data Integrity & Integration | 🔵 TrivialPlan job-run retention around this RESTRICT foreign key.
last_attempt_run_idisNOT NULLand usesonDelete: "restrict". Ajob_runsrow stays undeletable while any cache entry references it. Each cache key pins at most one run, so the set is bounded, but a job-run pruning or retention task must skip or resolve these referenced runs. Otherwise the delete fails with a foreign-key error.Consider excluding referenced runs in the retention query, or documenting the constraint next to the retention logic.
🤖 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/database/schema/cacheEntries.ts` around lines 36 - 41, The retention logic for job runs must account for the `cacheEntries.lastAttemptRunId` foreign key, which restricts deletion of referenced runs. Update the job-run pruning query or deletion flow to skip or otherwise resolve runs referenced by cache entries, and document this constraint next to the retention logic if appropriate.greenfield/src/server/database/validation/cacheEntries.ts (1)
63-76: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low valueDerive predicate inputs from the generated schemas.
CacheEntryRowLikeduplicates the row shape instead of usingv.InferOutput<typeof cacheEntrySelectSchema>in the select validator andv.InferOutput<typeof cacheEntryInsertSchema>in the insert validator.consecutiveFailuresis required in the interface but Drizzle’s insert schema makesconsecutive_failuresoptional because it has.default(0), so the predicate can drift across the SQL column definitions.🤖 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/database/validation/cacheEntries.ts` around lines 63 - 76, Remove the manually duplicated CacheEntryRowLike interface and derive predicate input types from the generated schemas: use v.InferOutput<typeof cacheEntrySelectSchema> for the select validator and v.InferOutput<typeof cacheEntryInsertSchema> for the insert validator. Update the relevant predicate signatures to consume those inferred types so schema defaults and SQL column changes remain reflected automatically.greenfield/src/server/domains/cache/systemHostProvider.ts (1)
56-87: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low valueAdd an explicit return type to the exported collector.
collectSystemHostPayloadhas no declared return type. The type is inferred fromv.parse. An explicit annotation keeps the public contract stable and improves declaration output.Line 20 also references
SystemHostFilesystemStats, which is not exported. Consumers that implementSystemHostAdaptercannot name that type. Export it for symmetry withSystemHostAdapter.♻️ Proposed annotation
-interface SystemHostFilesystemStats { +export interface SystemHostFilesystemStats {export async function collectSystemHostPayload( adapter: SystemHostAdapter = defaultSystemHostAdapter -) { +): Promise<v.InferOutput<typeof systemHostCachePayloadSchema>> {🤖 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/systemHostProvider.ts` around lines 56 - 87, Export the SystemHostFilesystemStats type used by SystemHostAdapter, and add an explicit return type to the exported collectSystemHostPayload function based on the validated system host cache payload schema. Keep the existing payload construction and validation behavior unchanged.greenfield/src/server/domains/cache/systemHostProvider.test.ts (1)
35-52: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low valueConsider covering the capacity-consistency rejection.
The tests cover unsafe bigint products and control characters in the hostname. The schema also enforces
freeBytes <= totalBytesfordiskandmemory. Add one case wherebavailexceedsblocks, and one wherefreeMemoryBytesexceedstotalMemoryBytes. These paths are the ones a real host adapter can hit under measurement skew.The assertion style without
awaitmatches the repository convention for Bun matcher types.🤖 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/systemHostProvider.test.ts` around lines 35 - 52, Extend the “rejects unsafe byte products and control-bearing host strings” test to cover capacity consistency: add a rootFilesystem case where bavail exceeds blocks and assert rejection, plus a memory case where freeMemoryBytes exceeds totalMemoryBytes and assert rejection. Preserve the existing non-awaited rejection assertion style and use the existing adapter and collectSystemHostPayload helpers.Source: Learnings
greenfield/src/server/domains/jobs/coordinator.ts (1)
660-690: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win
manualExposuregates cache persistence; use a dedicated capability instead.Line 665 allows cache writes only when
registration.manualExposure === "cache-write".manualExposuredescribes who may trigger a manual run. It does not describe whether the action may write cache entries. The two concerns are now coupled. An action that must write cache entries but must not be manually triggered cannot express that state, and it fails at runtime with "Cache attempt persistence is unavailable".Consider adding an explicit capability field, for example
cacheWrite: boolean, toJobActionDefinition, and gate on that field.♻️ Proposed gate change
commitCacheAttempt: async (outcome: JobCacheAttemptCommit) => { if ( - registration.manualExposure !== "cache-write" || + !registration.cacheWrite || options.commitCacheAttempt === undefined ) { throw new Error("Cache attempt persistence is 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/jobs/coordinator.ts` around lines 660 - 690, Decouple cache persistence from manual-run exposure in the commitCacheAttempt callback passed by the coordinator action: add an explicit cache-write capability to JobActionDefinition and gate availability using that capability instead of registration.manualExposure === "cache-write". Update the relevant action definitions and type plumbing so actions can write cache entries without being manually triggerable, while preserving the existing unavailable-error behavior when the capability or commit callback is absent.greenfield/src/server/domains/cache/repository.test.ts (1)
142-176: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winAdd coverage for the
"updated"realtime operation.The suite asserts
operation: "created"for a first success and covers the failure path. No test commits a second success for an existing key. TheexistingByKey.get(key) === undefinedbranch atgreenfield/src/server/domains/cache/repository.tsline 350 therefore never produces"updated"under test, and a regression that always emits"created"would pass.Add one case that commits two successful attempts for
system.hostand asserts the second realtime row usesoperation: "updated".🤖 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/repository.test.ts` around lines 142 - 176, Add a repository test covering the existing-key success path by committing two successful attempts for system.host through fixture.cache.commitAttempt, then query the realtime event for the second commit and assert its operation is "updated" while preserving the existing first-commit "created" coverage.
🤖 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/migrations/20260804022252_dashboard-foundation/snapshot.json`:
- Line 4: Do not modify the existing 20260804022252_dashboard-foundation
migration or its snapshot id d65c13c5-1ce8-4595-9328-52c607378fa0. Revert the
in-place snapshot change and add a new migration for the schema update,
preserving the original migration checksum for already-deployed environments.
In `@greenfield/src/server/domains/cache/repository.ts`:
- Around line 278-282: Make CacheRepository.commitAttempt async so exceptions
from validateAttemptOutcome and cacheAttemptAuthority become Promise rejections
consistent with its declared return type. Update the corresponding duplicate-key
test in repository.test.ts to capture the returned promise and assert it with
expect(promise).rejects..., without awaiting the assertion.
---
Nitpick comments:
In `@greenfield/src/server/database/schema/cacheEntries.ts`:
- Around line 36-41: The retention logic for job runs must account for the
`cacheEntries.lastAttemptRunId` foreign key, which restricts deletion of
referenced runs. Update the job-run pruning query or deletion flow to skip or
otherwise resolve runs referenced by cache entries, and document this constraint
next to the retention logic if appropriate.
In `@greenfield/src/server/database/validation/cacheEntries.ts`:
- Around line 63-76: Remove the manually duplicated CacheEntryRowLike interface
and derive predicate input types from the generated schemas: use
v.InferOutput<typeof cacheEntrySelectSchema> for the select validator and
v.InferOutput<typeof cacheEntryInsertSchema> for the insert validator. Update
the relevant predicate signatures to consume those inferred types so schema
defaults and SQL column changes remain reflected automatically.
In `@greenfield/src/server/domains/cache/repository.test.ts`:
- Around line 142-176: Add a repository test covering the existing-key success
path by committing two successful attempts for system.host through
fixture.cache.commitAttempt, then query the realtime event for the second commit
and assert its operation is "updated" while preserving the existing first-commit
"created" coverage.
In `@greenfield/src/server/domains/cache/systemHostProvider.test.ts`:
- Around line 35-52: Extend the “rejects unsafe byte products and
control-bearing host strings” test to cover capacity consistency: add a
rootFilesystem case where bavail exceeds blocks and assert rejection, plus a
memory case where freeMemoryBytes exceeds totalMemoryBytes and assert rejection.
Preserve the existing non-awaited rejection assertion style and use the existing
adapter and collectSystemHostPayload helpers.
In `@greenfield/src/server/domains/cache/systemHostProvider.ts`:
- Around line 56-87: Export the SystemHostFilesystemStats type used by
SystemHostAdapter, and add an explicit return type to the exported
collectSystemHostPayload function based on the validated system host cache
payload schema. Keep the existing payload construction and validation behavior
unchanged.
In `@greenfield/src/server/domains/jobs/coordinator.ts`:
- Around line 660-690: Decouple cache persistence from manual-run exposure in
the commitCacheAttempt callback passed by the coordinator action: add an
explicit cache-write capability to JobActionDefinition and gate availability
using that capability instead of registration.manualExposure === "cache-write".
Update the relevant action definitions and type plumbing so actions can write
cache entries without being manually triggerable, while preserving the existing
unavailable-error behavior when the capability or commit callback is absent.
🪄 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: ea6d8e0a-e444-4862-932e-5fbc30acc64c
⛔ Files ignored due to path filters (21)
greenfield/docs/generated/procedures.mdis excluded by!**/generated/**and included by**/*greenfield/docs/generated/realtime-events.mdis excluded by!**/generated/**and included by**/*greenfield/docs/generated/schemas/automationSecurity.createPrincipal.input.schema.jsonis excluded by!**/generated/**and included by**/*greenfield/docs/generated/schemas/automationSecurity.createPrincipal.output.schema.jsonis excluded by!**/generated/**and included by**/*greenfield/docs/generated/schemas/automationSecurity.disablePrincipal.output.schema.jsonis excluded by!**/generated/**and included by**/*greenfield/docs/generated/schemas/automationSecurity.listPrincipals.output.schema.jsonis excluded by!**/generated/**and included by**/*greenfield/docs/generated/schemas/automationSecurity.replaceCapabilities.input.schema.jsonis excluded by!**/generated/**and included by**/*greenfield/docs/generated/schemas/automationSecurity.replaceCapabilities.output.schema.jsonis excluded by!**/generated/**and included by**/*greenfield/docs/generated/schemas/cache.entries.realtime.payload.schema.jsonis excluded by!**/generated/**and included by**/*greenfield/docs/generated/schemas/cache.getEntry.input.schema.jsonis excluded by!**/generated/**and included by**/*greenfield/docs/generated/schemas/cache.getEntry.output.schema.jsonis excluded by!**/generated/**and included by**/*greenfield/docs/generated/schemas/cache.getStatus.input.schema.jsonis excluded by!**/generated/**and included by**/*greenfield/docs/generated/schemas/cache.getStatus.output.schema.jsonis excluded by!**/generated/**and included by**/*greenfield/docs/generated/schemas/cache.refreshEntry.input.schema.jsonis excluded by!**/generated/**and included by**/*greenfield/docs/generated/schemas/cache.refreshEntry.output.schema.jsonis excluded by!**/generated/**and included by**/*greenfield/docs/generated/schemas/events.stream.input.schema.jsonis excluded by!**/generated/**and included by**/*greenfield/docs/generated/schemas/events.stream.output.schema.jsonis excluded by!**/generated/**and included by**/*greenfield/docs/generated/schemas/schedules.get.output.schema.jsonis excluded by!**/generated/**and included by**/*greenfield/docs/generated/schemas/schedules.list.output.schema.jsonis excluded by!**/generated/**and included by**/*greenfield/docs/generated/schemas/schedules.update.output.schema.jsonis excluded by!**/generated/**and included by**/*greenfield/docs/generated/schemas/securityAudit.listEvents.output.schema.jsonis excluded by!**/generated/**and included by**/*
📒 Files selected for processing (77)
greenfield/docs/architecture/greenfield-rewrite/data-and-security.mdgreenfield/docs/architecture/greenfield-rewrite/progress.mdgreenfield/migrations/20260804022252_dashboard-foundation/migration.sqlgreenfield/migrations/20260804022252_dashboard-foundation/snapshot.jsongreenfield/scripts/documentation/artifacts.test.tsgreenfield/scripts/documentation/jsonSchema.test.tsgreenfield/scripts/documentation/jsonSchema.tsgreenfield/src/app/dashboardServer.test.tsgreenfield/src/app/dashboardServer.tsgreenfield/src/app/server.tsgreenfield/src/app/trpcHttpHandler.tsgreenfield/src/browser/api/trpcClient.test.tsgreenfield/src/browser/api/trpcClient.tsgreenfield/src/browser/jobs/JobsRoute.test.tsxgreenfield/src/browser/jobs/ScheduleDetail.tsxgreenfield/src/browser/jobs/ScheduleDetailStateReplay.test.tsxgreenfield/src/browser/jobs/ScheduleEditor.test.tsxgreenfield/src/browser/jobs/ScheduleTable.test.tsxgreenfield/src/browser/jobs/jobMutations.test.tsxgreenfield/src/browser/jobs/jobQueries.test.tsgreenfield/src/browser/jobs/scheduleEditorForm.test.tsgreenfield/src/browser/jobs/testSupport/ScheduleDetail.tsxgreenfield/src/contracts/cache.test.tsgreenfield/src/contracts/cache.tsgreenfield/src/contracts/cacheRealtime.test.tsgreenfield/src/contracts/cacheRealtime.tsgreenfield/src/contracts/contractRegistry.tsgreenfield/src/contracts/events.test.tsgreenfield/src/contracts/events.tsgreenfield/src/contracts/jobModel.test.tsgreenfield/src/contracts/jobModel.tsgreenfield/src/contracts/schedules.test.tsgreenfield/src/contracts/security.test.tsgreenfield/src/contracts/security.tsgreenfield/src/server/database/migrations/migrationGraph.test.tsgreenfield/src/server/database/schema/automationPrincipalCapabilities.tsgreenfield/src/server/database/schema/cacheEntries.test.tsgreenfield/src/server/database/schema/cacheEntries.tsgreenfield/src/server/database/schema/drizzleSchema.tsgreenfield/src/server/database/validation/cacheEntries.test.tsgreenfield/src/server/database/validation/cacheEntries.tsgreenfield/src/server/domains/cache/errors.tsgreenfield/src/server/domains/cache/procedures.test.tsgreenfield/src/server/domains/cache/procedures.tsgreenfield/src/server/domains/cache/providerRegistry.tsgreenfield/src/server/domains/cache/records.tsgreenfield/src/server/domains/cache/repository.test.tsgreenfield/src/server/domains/cache/repository.tsgreenfield/src/server/domains/cache/routes.tsgreenfield/src/server/domains/cache/service.test.tsgreenfield/src/server/domains/cache/service.tsgreenfield/src/server/domains/cache/systemHostProvider.test.tsgreenfield/src/server/domains/cache/systemHostProvider.tsgreenfield/src/server/domains/cache/testSupport/service.tsgreenfield/src/server/domains/jobs/actionExecutors.test.tsgreenfield/src/server/domains/jobs/actionExecutors.tsgreenfield/src/server/domains/jobs/actionRegistry.test.tsgreenfield/src/server/domains/jobs/actionRegistry.tsgreenfield/src/server/domains/jobs/coordinator.test.tsgreenfield/src/server/domains/jobs/coordinator.tsgreenfield/src/server/domains/jobs/manualEnqueue.tsgreenfield/src/server/domains/jobs/records.tsgreenfield/src/server/domains/jobs/registeredSchedule.tsgreenfield/src/server/domains/jobs/repository.tsgreenfield/src/server/domains/jobs/service.test.tsgreenfield/src/server/domains/jobs/service.tsgreenfield/src/server/domains/jobs/workerRuntime.test.tsgreenfield/src/server/domains/jobs/workerRuntime.tsgreenfield/src/server/domains/jobs/workerSystem.test.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/databaseMigrationManifest.tsgreenfield/src/test/parity/fixtures/greenfield-contracts.jsongreenfield/src/test/parity/fixtures/legacy-endpoints.json
📜 Review details
⏰ Context from checks skipped due to timeout. (2)
- GitHub Check: dashboard-checks
- GitHub Check: Analyze JavaScript and TypeScript
🧰 Additional context used
🧠 Learnings (2)
📚 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/browser/jobs/scheduleEditorForm.test.tsgreenfield/src/browser/api/trpcClient.test.tsgreenfield/src/contracts/cache.test.tsgreenfield/src/contracts/jobModel.test.tsgreenfield/src/contracts/events.test.tsgreenfield/src/server/database/schema/cacheEntries.test.tsgreenfield/src/app/dashboardServer.test.tsgreenfield/src/contracts/cacheRealtime.test.tsgreenfield/src/server/database/migrations/migrationGraph.test.tsgreenfield/src/browser/jobs/jobQueries.test.tsgreenfield/src/server/database/validation/cacheEntries.test.tsgreenfield/scripts/documentation/jsonSchema.test.tsgreenfield/src/server/domains/cache/procedures.test.tsgreenfield/src/server/domains/jobs/workerRuntime.test.tsgreenfield/src/server/domains/jobs/actionRegistry.test.tsgreenfield/src/contracts/schedules.test.tsgreenfield/src/server/domains/jobs/workerSystem.test.tsgreenfield/src/server/domains/jobs/actionExecutors.test.tsgreenfield/src/server/domains/jobs/service.test.tsgreenfield/src/server/domains/cache/service.test.tsgreenfield/src/server/domains/cache/repository.test.tsgreenfield/src/contracts/security.test.tsgreenfield/src/server/domains/cache/systemHostProvider.test.tsgreenfield/src/server/domains/jobs/coordinator.test.tsgreenfield/src/server/trpc/context.test.ts
📚 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/documentation/artifacts.test.tsgreenfield/src/server/database/schema/automationPrincipalCapabilities.tsgreenfield/src/browser/jobs/scheduleEditorForm.test.tsgreenfield/src/server/database/schema/drizzleSchema.tsgreenfield/src/server/trpc/appRouter.tsgreenfield/src/browser/api/trpcClient.test.tsgreenfield/src/contracts/cache.test.tsgreenfield/src/server/domains/cache/testSupport/service.tsgreenfield/src/contracts/jobModel.test.tsgreenfield/src/server/domains/cache/procedures.tsgreenfield/src/contracts/events.test.tsgreenfield/src/server/database/schema/cacheEntries.test.tsgreenfield/src/app/dashboardServer.test.tsgreenfield/src/contracts/jobModel.tsgreenfield/src/server/trpc/context.tsgreenfield/src/server/domains/jobs/manualEnqueue.tsgreenfield/src/contracts/cacheRealtime.test.tsgreenfield/src/server/database/migrations/migrationGraph.test.tsgreenfield/src/browser/jobs/jobQueries.test.tsgreenfield/src/contracts/cacheRealtime.tsgreenfield/src/server/domains/cache/systemHostProvider.tsgreenfield/src/server/test/support/requestContext.tsgreenfield/src/server/database/validation/cacheEntries.test.tsgreenfield/scripts/documentation/jsonSchema.test.tsgreenfield/src/server/domains/cache/procedures.test.tsgreenfield/src/server/domains/jobs/records.tsgreenfield/src/app/server.tsgreenfield/src/contracts/security.tsgreenfield/src/server/domains/cache/records.tsgreenfield/src/server/database/validation/cacheEntries.tsgreenfield/src/server/domains/cache/routes.tsgreenfield/src/shared/databaseMigrationManifest.tsgreenfield/src/server/domains/jobs/workerRuntime.test.tsgreenfield/src/server/trpc/procedureErrorPolicy.tsgreenfield/src/server/domains/jobs/actionRegistry.test.tsgreenfield/scripts/documentation/jsonSchema.tsgreenfield/src/contracts/schedules.test.tsgreenfield/src/server/domains/jobs/workerSystem.test.tsgreenfield/src/server/domains/jobs/actionExecutors.test.tsgreenfield/src/browser/api/trpcClient.tsgreenfield/src/server/database/schema/cacheEntries.tsgreenfield/src/server/domains/cache/errors.tsgreenfield/src/server/domains/jobs/service.test.tsgreenfield/src/server/domains/cache/service.test.tsgreenfield/src/server/domains/jobs/workerRuntime.tsgreenfield/src/contracts/contractRegistry.tsgreenfield/src/app/trpcHttpHandler.tsgreenfield/src/server/domains/cache/repository.test.tsgreenfield/src/contracts/events.tsgreenfield/src/server/domains/cache/providerRegistry.tsgreenfield/src/app/dashboardServer.tsgreenfield/src/contracts/security.test.tsgreenfield/src/server/domains/jobs/actionExecutors.tsgreenfield/src/server/domains/cache/systemHostProvider.test.tsgreenfield/src/server/domains/jobs/repository.tsgreenfield/src/server/domains/jobs/coordinator.test.tsgreenfield/src/server/domains/cache/repository.tsgreenfield/src/server/domains/cache/service.tsgreenfield/src/server/domains/jobs/coordinator.tsgreenfield/src/server/domains/jobs/registeredSchedule.tsgreenfield/src/server/domains/jobs/service.tsgreenfield/src/server/trpc/context.test.tsgreenfield/src/contracts/cache.tsgreenfield/src/server/domains/jobs/actionRegistry.ts
🪛 Betterleaks (1.7.3)
greenfield/src/contracts/cache.test.ts
[high] 137-137: Detected a Generic API Key, potentially exposing access to various services and sensitive operations.
(generic-api-key)
[high] 144-144: Detected a Generic API Key, potentially exposing access to various services and sensitive operations.
(generic-api-key)
🔇 Additional comments (88)
greenfield/src/server/domains/jobs/actionExecutors.test.ts (1)
1-117: LGTM!greenfield/src/server/domains/jobs/actionRegistry.test.ts (1)
4-26: LGTM!Also applies to: 39-39, 49-51, 64-75
greenfield/src/server/domains/jobs/coordinator.test.ts (1)
7-12: LGTM!Also applies to: 445-452, 870-870, 1260-1260, 1473-1478, 1588-1588, 1618-1618, 1645-1645, 1678-1678, 1702-1782, 1823-1823, 1887-1887, 1936-1936
greenfield/src/server/trpc/context.test.ts (1)
4-4: LGTM!Also applies to: 41-41, 70-70, 104-104, 136-136, 179-179
greenfield/docs/architecture/greenfield-rewrite/progress.md (1)
10-18: LGTM!Also applies to: 972-999
greenfield/docs/architecture/greenfield-rewrite/data-and-security.md (1)
210-210: LGTM!greenfield/migrations/20260804022252_dashboard-foundation/snapshot.json (1)
45-48: LGTM!Also applies to: 965-1124, 3765-3779, 4095-4103, 4832-4853, 6163-6163, 6198-6287
greenfield/src/contracts/cache.ts (1)
20-120: LGTM!Also applies to: 122-199, 203-263, 265-308, 310-350, 352-423
greenfield/src/contracts/cache.test.ts (1)
13-32: LGTM!Also applies to: 34-84, 86-132, 134-173
greenfield/src/contracts/jobModel.test.ts (1)
311-311: LGTM!greenfield/src/server/database/schema/cacheEntries.ts (1)
25-35: LGTM!Also applies to: 42-51, 52-123
greenfield/src/server/database/schema/cacheEntries.test.ts (1)
9-61: LGTM!greenfield/src/server/database/validation/cacheEntries.ts (2)
44-61: LGTM!Also applies to: 82-117, 119-132
22-33: 🩺 Stability & AvailabilityNo change needed.
parseJsonTextalready preventsJSON.parsefailures from escaping the validation predicate by catching syntax errors and returningundefined.> Likely an incorrect or invalid review comment.greenfield/src/contracts/jobModel.ts (1)
717-717: 🗄️ Data Integrity & IntegrationNo change needed:
ScheduleSummaryalways setsmanualRunAvailable.
toScheduleSummary()mapsmanualRunAvailablefrom registered schedule exposure state, so schedule producers pass it through before schema validation.greenfield/migrations/20260804022252_dashboard-foundation/migration.sql (1)
142-142: LGTM!Also applies to: 159-193, 416-416
greenfield/scripts/documentation/artifacts.test.ts (1)
196-196: LGTM!greenfield/scripts/documentation/jsonSchema.ts (1)
40-49: LGTM!Also applies to: 167-198
greenfield/src/contracts/cacheRealtime.test.ts (1)
1-53: LGTM!greenfield/src/contracts/cacheRealtime.ts (1)
1-72: LGTM!greenfield/src/contracts/contractRegistry.ts (1)
6-7: LGTM!Also applies to: 34-34, 85-85
greenfield/src/contracts/events.test.ts (1)
5-5: LGTM!Also applies to: 23-23, 96-124
greenfield/src/contracts/events.ts (1)
12-16: LGTM!Also applies to: 39-39, 57-57, 67-67, 108-108
greenfield/scripts/documentation/jsonSchema.test.ts (1)
142-143: LGTM!Also applies to: 155-155
greenfield/src/contracts/schedules.test.ts (1)
26-26: LGTM!greenfield/src/contracts/security.test.ts (1)
21-22: LGTM!greenfield/src/contracts/security.ts (1)
97-98: LGTM!greenfield/src/server/database/migrations/migrationGraph.test.ts (1)
42-42: LGTM!Also applies to: 199-199
greenfield/src/server/database/schema/automationPrincipalCapabilities.ts (1)
21-21: LGTM!greenfield/src/server/database/schema/drizzleSchema.ts (1)
14-14: LGTM!greenfield/src/server/database/validation/cacheEntries.test.ts (1)
1-76: LGTM!greenfield/src/server/domains/jobs/actionRegistry.ts (4)
27-60: LGTM!Also applies to: 79-93, 96-113
115-172: LGTM!
174-217: LGTM!
219-247: LGTM!Also applies to: 255-257
greenfield/src/server/domains/jobs/actionExecutors.ts (4)
15-49: LGTM!
125-191: LGTM!
91-121: 🗄️ Data Integrity & IntegrationNo change needed for
jobRunResultSchemashape.
jobRunResultSchemausesjsonObjectSchema, which accepts bounded JSON object fields, so{ cacheKeys, completedAtMs }is not rejected by coordinator result validation.> Likely an incorrect or invalid review comment.
66-90: 🩺 Stability & AvailabilityNo change needed for these failure-path cases.
Effect.catchis valid ineffect4.0.0-beta.104, and the coordinator handlesJobClaimLostErrorfrom a lostcommitCacheAttemptvia the existing claim-lost settlement path.greenfield/src/server/domains/jobs/coordinator.ts (2)
15-21: LGTM!Also applies to: 101-120, 324-330, 528-539, 1021-1021, 1050-1052
164-167: 🎯 Functional CorrectnessNo prod callers omitted
findActionand no other default resolver is needed.greenfield/src/server/domains/jobs/workerRuntime.ts (1)
11-13: LGTM!Also applies to: 44-57, 89-94, 231-239
greenfield/src/server/domains/jobs/workerSystem.test.ts (1)
3-14: LGTM!Also applies to: 67-69, 159-263
greenfield/src/server/domains/cache/systemHostProvider.ts (1)
1-49: LGTM!greenfield/src/server/domains/cache/systemHostProvider.test.ts (1)
1-33: LGTM!greenfield/src/app/dashboardServer.test.ts (2)
9-9: LGTM!Also applies to: 305-318
320-332: 🎯 Functional CorrectnessNo change needed.
cache.getStatusacceptsemptyInputSchema, which accepts{ }viav.optional(v.strictObject({}), {});{ json: {} }parses through that optional wrapper, andcacheStatusBodycontainsresultonly once.greenfield/src/test/parity/fixtures/greenfield-contracts.json (1)
173-184: LGTM!greenfield/src/test/parity/fixtures/legacy-endpoints.json (1)
276-276: LGTM!Also applies to: 302-302, 1416-1416
greenfield/src/shared/databaseMigrationManifest.ts (1)
15-18: 🗄️ Data Integrity & IntegrationNo action needed. The migration loader treats a manifest and migration artifact change as a checksum mismatch before runtime startup, so a database with the old checksum cannot proceed silently.
greenfield/src/server/domains/jobs/manualEnqueue.ts (1)
1-36: LGTM!greenfield/src/server/domains/jobs/records.ts (1)
30-30: LGTM!Also applies to: 204-206
greenfield/src/server/domains/jobs/registeredSchedule.ts (1)
1-1: LGTM!Also applies to: 12-19
greenfield/src/server/domains/jobs/repository.ts (1)
425-429: LGTM!Also applies to: 712-729, 1184-1184, 1332-1332, 2503-2514
greenfield/src/server/domains/jobs/service.test.ts (1)
219-238: LGTM!greenfield/src/server/domains/jobs/service.ts (1)
38-49: LGTM!Also applies to: 371-375, 477-503, 562-562, 879-880
greenfield/src/browser/jobs/JobsRoute.test.tsx (1)
145-145: LGTM!greenfield/src/browser/jobs/ScheduleEditor.test.tsx (1)
20-20: LGTM!greenfield/src/browser/jobs/ScheduleTable.test.tsx (1)
18-18: LGTM!greenfield/src/browser/jobs/jobMutations.test.tsx (1)
147-147: LGTM!greenfield/src/browser/jobs/jobQueries.test.ts (1)
74-74: LGTM!greenfield/src/browser/jobs/scheduleEditorForm.test.ts (1)
45-45: LGTM!greenfield/src/server/domains/jobs/workerRuntime.test.ts (1)
6-6: LGTM!Also applies to: 78-87, 199-199
greenfield/src/server/domains/cache/providerRegistry.ts (1)
1-100: LGTM!greenfield/src/server/domains/cache/records.ts (1)
1-74: LGTM!greenfield/src/server/domains/cache/repository.ts (3)
362-390: LGTM!
89-116: 🗄️ Data Integrity & IntegrationNo change needed. The scheduled run
payloadJsonis already stored fromschedule.actionPayloadJson, which is defined byJSON.stringify(registration.actionPayload)for cached schedules.
270-275: 🗄️ Data Integrity & IntegrationConfirm the
transactionconfig argument is honored, and narrow the double type assertion.
database.transaction.bind(database) as unknown as <T>(...)removes Drizzle’s own typings for both the callback and the config object. IfSQLiteBunDatabase.transactionin drizzle-orm 1.0.0-rc.4 does not accept a second config argument,{ behavior: "immediate" }is ignored at runtime and the claim-fence code runs in a deferred transaction. Use the narrowest cast that still compiles.greenfield/src/server/domains/cache/repository.test.ts (1)
386-430: LGTM!greenfield/src/server/trpc/appRouter.ts (1)
2-2: LGTM!Also applies to: 50-50, 69-69
greenfield/src/server/trpc/procedureErrorPolicy.ts (1)
202-210: LGTM!greenfield/src/browser/api/trpcClient.ts (1)
75-78: LGTM!greenfield/src/browser/api/trpcClient.test.ts (1)
172-193: LGTM!greenfield/src/browser/jobs/ScheduleDetail.tsx (1)
264-278: LGTM!greenfield/src/browser/jobs/ScheduleDetailStateReplay.test.tsx (1)
15-21: LGTM!greenfield/src/browser/jobs/testSupport/ScheduleDetail.tsx (1)
19-19: LGTM!Also applies to: 53-53
greenfield/src/server/domains/cache/errors.ts (1)
1-17: LGTM!greenfield/src/server/domains/cache/routes.ts (1)
1-56: LGTM!greenfield/src/server/domains/cache/service.ts (1)
1-332: LGTM!greenfield/src/server/domains/cache/testSupport/service.ts (1)
1-26: LGTM!greenfield/src/server/domains/cache/procedures.ts (1)
1-8: LGTM!greenfield/src/server/domains/cache/procedures.test.ts (1)
1-143: LGTM!greenfield/src/server/domains/cache/service.test.ts (1)
1-199: LGTM!greenfield/src/app/dashboardServer.ts (1)
8-9: LGTM!Also applies to: 93-93, 297-302, 325-325
greenfield/src/app/server.ts (1)
6-6: LGTM!Also applies to: 138-138, 188-188
greenfield/src/app/trpcHttpHandler.ts (1)
4-4: LGTM!Also applies to: 42-42, 222-222
greenfield/src/server/test/support/requestContext.ts (1)
10-11: LGTM!Also applies to: 399-399, 428-428, 520-520, 547-547
greenfield/src/server/trpc/context.ts (1)
3-3: LGTM!Also applies to: 38-38, 60-60, 93-93
Summary
cache_entriesprojection with separate last-attempt state and derived freshnesscache.refresh.system-hostaction and dailycache.system-hostschedule, with worker-only execution and a strictsystem.hostpayloadcache.getEntry,cache.getStatus, andcache.refreshEntryprocedures through the production server/runtime compositionCorrectness and security
cache.getStatusreturns at most 128 rows plus explicittotalCount,truncated, and one snapshot clockcache:read/cache:writecapabilities and exactcache.entriesrealtime identity are enforced end to endBehavior and regression coverage
cache.getStatuslocks the 128-row response boundary, total count, truncation marker, one generated-at clock, and freshness consistencyVerification
bun run build:releasebun run test:bun— 1573/1573bun run test:browser— 219/219 across all browser partitionsbun run typecheck:bunbun run typecheck:browserbun run lint:bunbun run lint:browserbun run format:checkbun run docs:checkbun run db:check—ok / no_changesbun run check:boundariesgit diff --checkStack and scope
c6ab45a186e6e795e216814ee83fd2e34ae27d9069bc9140fc5c0e0e0c99dff538adb6c91c6fdf25cache.getHeartbeat, OpenClaw cron integration, cache browser consumption, metrics, and overview for subsequent slicesRisk checklist
Deployment / operations
Notes for reviewers