Skip to content

feat(rewrite): add Phase 3 agent directory - #397

Merged
rajohan merged 3 commits into
mira/greenfield-rewrite-phase-three-corefrom
mira/greenfield-rewrite-phase-three-agents
Aug 24, 2026
Merged

feat(rewrite): add Phase 3 agent directory#397
rajohan merged 3 commits into
mira/greenfield-rewrite-phase-three-corefrom
mira/greenfield-rewrite-phase-three-agents

Conversation

@mira-2026

@mira-2026 mira-2026 commented Aug 7, 2026

Copy link
Copy Markdown
Collaborator

Summary

  • add the reviewed five-agent directory, agents:read / agents:write capabilities, durable task-run history, atomic realtime events, and the complete validated tRPC surface
  • add /agents with TanStack DB, Query, Table, and Virtual projections for configuration, current status, and keyset-paginated history
  • extend the mutable fresh-database baseline, generated schema identity, parity inventory, and Phase 3 progress evidence
  • harden authenticated cache resets, realtime fallback refreshes, agent ordering, and review-identified browser failure paths

Behavior and regression coverage

  • /agents renders reviewed roles, current task status, and keyset-paginated history with corrected heading hierarchy
  • authenticated cache resets recreate query-backed agent collections even when prior cleanup fails; regression coverage observes both cleanup failures and the replacement registry
  • authentication actions preserve the original safe operation error when fallback cache teardown also fails
  • terminal realtime resync keeps periodic refresh active, and rejected timer-driven invalidation stays contained
  • agent task-run ordering remains monotonic across clock regression, while exact, list, and history projections agree
  • contract tests cover maximum task-history limits, cursor/result consistency, and the shared agent timestamp policy

Verification

  • Repository lint: cd greenfield && bun run lint
  • Repository formatting: cd greenfield && bun run format:check
  • Frontend build: bun run build:frontend — not applicable to this isolated greenfield slice; the browser artifact was built by cd greenfield && bun run build:release
  • Frontend tests/coverage: bun run test:frontend:coverage — legacy frontend is outside this slice; greenfield browser coverage ran below
  • Backend build: bun run build:backend — not applicable to this isolated greenfield slice; process artifacts were built by cd greenfield && bun run build:release
  • Backend tests/coverage: bun run test:backend:coverage — legacy backend is outside this slice; full greenfield coverage ran below
  • Focused regression tests: agent contracts/service/procedures (13/13) and browser cache/auth/realtime/route coverage (18/18)
  • Manual UI/API smoke check, if relevant — inactive pre-cutover slice; component, HTTP system, and release-lifecycle tests cover the executable paths

Additional greenfield gates:

  • bun run typecheck
  • bun run check:boundaries
  • bun run docs:check
  • bun run db:check
  • bun run test:coverage — 1,382 Bun tests + 66 browser tests, 0 failures, 92.06% line coverage
  • bun run build:release — clean-source release for 47fac9196081c19deb1c16034f09d63e92aa33f2

Risk checklist

  • No secrets, tokens, .env files, database dumps, or runtime state committed
  • Auth, Gateway, terminal, file, Docker, or settings changes were reviewed carefully
  • New/changed API routes enforce the expected authentication and validation
  • Migrations or data-shape changes include a rollout/rollback note, if relevant
  • Runtime/reconnect behavior preserves ordering, idempotency, and recovery
  • UI changes include screenshots or a short description of visible changes

The migration edits update the unpublished fresh-database greenfield baseline only. This slice remains inactive until the final supervised cutover; rollback before cutover is to revert the slice and rebuild the fresh baseline.

Visible UI change: the new /agents route shows five agent cards, live current-task state, and a virtualized task-history table. Agent card headings are level 3 beneath the page's “Current status” section.

Deployment / operations

  • No deploy/restart needed
  • Deploy/restart needed after merge: none; this stack remains inactive until supervised cutover
  • Config/secrets changes needed: none
  • Rollback path verified: revert this PR before cutover and regenerate the unpublished fresh-database baseline/release artifacts

Notes for reviewers

  • focus on authenticated collection lifecycle, monotonic task-run transitions, and realtime resync recovery
  • effect@4.0.0-beta.104 preserves the exact typed error instance through Effect.runPromise; the real procedure regression verifies unknown agents map to NOT_FOUND
  • stack base: feat(rewrite): add Phase 3 task domain #396 at locked head 68aa8523f30db5a52369eb173c596441229ef269

@mira-2026
mira-2026 requested a review from rajohan as a code owner August 7, 2026 16:33
@mira-2026 mira-2026 added status: needs-review Ready for human or agent review type: feature Adds user-visible functionality type: tests Adds or updates automated tests/coverage area: frontend Frontend UI, client state, routing, and browser behavior area: backend Backend API, server routes, services, and integrations area: database Database dashboard, Postgres, PgBouncer, or query views area: openclaw OpenClaw gateway/API integration and runtime behavior area: ops Operational actions, deploys, services, backups, and health labels Aug 7, 2026
@coderabbitai

coderabbitai Bot commented Aug 7, 2026

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

@mira-2026, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 29 minutes

You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository.

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 6f8ae1aa-8ca6-4f3a-b7d9-7ee23ca65534

📥 Commits

Reviewing files that changed from the base of the PR and between 31bc23e and 47fac91.

📒 Files selected for processing (13)
  • greenfield/src/browser/agents/AgentStatusGrid.tsx
  • greenfield/src/browser/agents/AgentsRoute.test.tsx
  • greenfield/src/browser/agents/AgentsRoute.tsx
  • greenfield/src/browser/api/useRealtimeQueryInvalidation.ts
  • greenfield/src/browser/auth/LoginRoute.test.tsx
  • greenfield/src/browser/auth/useAuthenticationAction.ts
  • greenfield/src/browser/data/dashboardCollections.test.ts
  • greenfield/src/browser/data/dashboardCollections.ts
  • greenfield/src/browser/tasks/useTaskRealtimeInvalidation.test.tsx
  • greenfield/src/contracts/agentModel.ts
  • greenfield/src/contracts/agents.test.ts
  • greenfield/src/contracts/agents.ts
  • greenfield/src/server/domains/agents/service.ts
📝 Walkthrough

Summary by CodeRabbit

  • New Features
    • Added an Agents dashboard with agent configuration, availability, current activity, and task status.
    • Added paginated task history with agent, task, status, start time, and completion details.
    • Added live status updates with automatic refresh fallback.
    • Added agent navigation and protected access controls for viewing and updating agent metadata.
  • Bug Fixes
    • Improved cache cleanup during authentication changes.
    • Improved realtime refresh handling when synchronization requires recovery.
  • Accessibility
    • Added accessible labels to data tables.

Walkthrough

Changes

Agent domain and persistence

Layer / File(s) Summary
Agent contracts and access policies
greenfield/src/contracts/*, greenfield/src/server/domains/agents/directory.ts
Added validated agent definitions, statuses, task runs, realtime events, procedure contracts, capabilities, and a code-owned directory.
Task-run persistence and service
greenfield/src/server/database/*, greenfield/src/migrations/*, greenfield/src/server/domains/agents/{repository,service,routes}.ts
Added durable task-run storage, lifecycle constraints, indexed history, actor attribution, transactional updates, realtime events, and authorized tRPC procedures.
Server and test composition
greenfield/src/app/*, greenfield/src/server/trpc/*, greenfield/src/server/test/support/*
Injected AgentService through server composition, request context, routers, and test fixtures.

Browser dashboard

Layer / File(s) Summary
Agent data and realtime refresh
greenfield/src/browser/agents/*, greenfield/src/browser/api/*
Added query-backed agent collections, cursor-paginated history, live invalidation, fallback refresh, and contract loading.
Agents route and presentation
greenfield/src/browser/agents/*, greenfield/src/browser/router.tsx, greenfield/src/browser/routes/agents.lazy.tsx, greenfield/src/browser/layout/DashboardShell.tsx
Added the authenticated /agents route, status cards, task-history table, refresh controls, pagination, and navigation.
Collection lifecycle and authentication
greenfield/src/browser/data/*, greenfield/src/browser/auth/*, greenfield/src/browser/application.tsx
Added browser collection providers and serialized cleanup/reset behavior. Authentication cache resets now recreate collections before clearing or restoring query state.

Validation and documentation

Layer / File(s) Summary
Tests, schemas, and parity
greenfield/src/**/*.test.*, greenfield/scripts/documentation/*, greenfield/src/test/parity/*, greenfield/docs/architecture/*
Added contract, migration, service, procedure, route, realtime, JSON Schema, documentation, and parity coverage for agents.
Supporting UI and repository configuration
greenfield/.gitignore, greenfield/src/browser/ui/*, greenfield/src/shared/databaseMigrationManifest.ts
Scoped ignored data paths, added table accessibility labels and page-header actions, and updated migration hashes.

Estimated code review effort: 5 (Critical) | ~120 minutes

Possibly related PRs

Suggested labels: area: tasks

🚥 Pre-merge checks | ✅ 4
✅ Passed checks (4 passed)
Check name Status Explanation
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Title check ✅ Passed The title clearly and concisely identifies the main change: adding the Phase 3 agent directory.
Description check ✅ Passed The description includes all required sections and provides clear behavior, verification, risk, deployment, rollback, and reviewer information.

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 5

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
greenfield/src/browser/auth/useAuthenticationAction.ts (1)

30-37: 🩺 Stability & Availability | 🟡 Minor | ⚡ Quick win

Keep the original error when the fallback reset fails.

resetAuthenticatedBrowserCache calls collections.reset(), and reset() rejects with a TypeError after the registry is cleaned up. If line 34 rejects, that rejection escapes the catch block and throw error on line 36 never runs. The user then sees the reset failure message instead of the original operation failure.

🛡️ Proposed fix
             } catch (error: unknown) {
                 try {
                     await refreshAuthenticationStatus();
                 } catch {
-                    await resetAuthenticatedBrowserCache(queryClient, collections);
+                    try {
+                        await resetAuthenticatedBrowserCache(queryClient, collections);
+                    } catch {
+                        // Preserve the original operation failure.
+                    }
                 }
                 throw error;
             }
🤖 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/auth/useAuthenticationAction.ts` around lines 30 - 37,
Preserve the original operation error in the catch path of the authentication
action: ensure failures from resetAuthenticatedBrowserCache do not escape or
replace the error ultimately rethrown by the outer catch. Update the fallback
handling around refreshAuthenticationStatus and resetAuthenticatedBrowserCache
so the original error is always thrown.
🧹 Nitpick comments (5)
greenfield/src/browser/data/dashboardCollections.ts (2)

54-63: 🩺 Stability & Availability | 🔵 Trivial | ⚡ Quick win

Recreate the collections even when the previous cleanup fails.

If cleanupAgentCollections(previousAgents) rejects on line 60, line 61 never runs. The registry then keeps serving previousAgents, whose sub-collections may already be cleaned up. Consumers read a half-torn-down registry after an authentication boundary reset.

Move the recreation into a finally block so the registry always exposes fresh collections.

♻️ Proposed refactor
         async reset(): Promise<void> {
             await enqueue(async () => {
                 if (cleaned) {
                     throw new TypeError("Dashboard collections are cleaned up");
                 }
                 const previousAgents = agents;
-                await cleanupAgentCollections(previousAgents);
-                agents = createAgentCollections(queryClient, trpcClient);
+                try {
+                    await cleanupAgentCollections(previousAgents);
+                } finally {
+                    agents = createAgentCollections(queryClient, trpcClient);
+                }
             });
         },
🤖 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/data/dashboardCollections.ts` around lines 54 - 63,
Update reset() so createAgentCollections always replaces agents in a finally
block after cleanupAgentCollections(previousAgents), while preserving the
cleaned-state check and propagating cleanup errors.

16-21: 🩺 Stability & Availability | 🔵 Trivial | 💤 Low value

Promise.all leaves the second cleanup rejection unobserved.

If definitions.cleanup() rejects, Promise.all rejects immediately. A later rejection from statuses.cleanup() becomes an unhandled rejection. Use Promise.allSettled and then report the failures.

🤖 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/data/dashboardCollections.ts` around lines 16 - 21,
Update cleanupAgentCollections to use Promise.allSettled for
definitions.cleanup() and statuses.cleanup(), then inspect the settled results
and report any rejected cleanup operations through the existing error-reporting
mechanism.
greenfield/src/browser/api/useRealtimeQueryInvalidation.ts (1)

30-36: 🩺 Stability & Availability | 🔵 Trivial | ⚡ Quick win

Handle rejections from refreshQueries.

Line 34 discards the promise with void. If refreshQueries rejects, the rejection is unhandled and reaches the global handler. Add a .catch so a transient invalidation failure does not surface as an unhandled rejection.

🛡️ Proposed fix
             refreshTimer = setTimeout(() => {
                 refreshTimer = undefined;
-                void refreshQueries(queryClient);
+                void refreshQueries(queryClient).catch(() => undefined);
             }, refreshDelayMs);
🤖 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/api/useRealtimeQueryInvalidation.ts` around lines 30 -
36, Update the setTimeout callback in scheduleRefresh to attach a catch handler
to the promise returned by refreshQueries(queryClient), while preserving the
existing refreshTimer reset and scheduling behavior. Ensure any rejection is
handled locally so it does not become an unhandled promise rejection.
greenfield/src/contracts/agentModel.ts (1)

95-95: 🗄️ Data Integrity & Integration | 🔵 Trivial | ⚡ Quick win

Reuse one shared agentTimestampSchema across agent contracts.

agentModel.ts and agents.ts each declare separate agentTimestampSchema constants, so changes to the agent timestamp validation can drift between status and cursor schemas. Export one agentTimestampSchema and import it where needed.

🤖 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/agentModel.ts` at line 95, Consolidate the duplicate
agentTimestampSchema declarations by exporting the existing shared schema from
its defining module and importing it in the other agent contract module. Update
both status and cursor schema usage to reference this single
agentTimestampSchema, preserving the existing validation message and behavior.
greenfield/src/contracts/agents.test.ts (1)

75-102: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Add coverage for the limit bound and the cursor-consistency check.

The test name states "defaults and bounds", but the body only checks the default limit and the ordering check. Two contract rules in agents.ts stay untested: agentTaskHistoryLimitSchema rejects a limit above agentTaskHistoryPageMaximum, and agentTaskHistoryCursorIsConsistent rejects a nextCursor that does not match the final row.

♻️ Proposed additional assertions
         expect(v.parse(listAgentTaskHistoryInputSchema, {})).toEqual({
             limit: agentTaskHistoryPageDefault,
         });
+        expect(
+            v.safeParse(listAgentTaskHistoryInputSchema, {
+                limit: agentTaskHistoryPageMaximum + 1,
+            }).success
+        ).toBeFalse();
+        expect(
+            v.safeParse(listAgentTaskHistoryResultSchema, {
+                nextCursor: { id: secondRunId, startedAtMs: 2000 },
+                runs: [
+                    {
+                        agentId: "main",
+                        id: firstRunId,
+                        lastActivityAtMs: 1000,
+                        startedAtMs: 1000,
+                        status: "active",
+                        task: "Newer task",
+                    },
+                ],
+            }).success
+        ).toBeFalse();

agentTaskHistoryPageMaximum must be added to the import list at line 5.

🤖 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/agents.test.ts` around lines 75 - 102, Extend the
“defaults and bounds newest-first task history” test to assert that
agentTaskHistoryLimitSchema rejects a limit above agentTaskHistoryPageMaximum,
and that agentTaskHistoryCursorIsConsistent rejects a nextCursor inconsistent
with the final run. Add agentTaskHistoryPageMaximum to the existing imports and
preserve the current default and ordering assertions.
🤖 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/agents/AgentsRoute.tsx`:
- Around line 48-54: Update the refresh function to attach a rejection handler
to the Promise.all aggregate created from the three refetch calls, routing
failures to the existing error-reporting mechanism such as console.error.
Preserve the current refetch behavior and query-driven rendered error state.

In `@greenfield/src/browser/agents/AgentStatusGrid.tsx`:
- Around line 77-83: Update the agent card Heading in AgentStatusGrid to use
level 3 instead of level 2, preserving the existing id, size, and displayName
rendering so the cards are subordinate to the “Current status” section heading.

In `@greenfield/src/server/domains/agents/routes.ts`:
- Around line 19-32: The runAgentEffect function currently checks the rejected
Effect wrapper instead of the underlying typed failure, so AgentNotFoundError is
not mapped correctly. Update runAgentEffect to inspect or handle the Effect
cause before testing AgentNotFoundError, using an appropriate Effect mechanism
such as catchTag, runPromiseExit with cause extraction, or equivalent, while
preserving the existing NOT_FOUND TRPCError mapping.

In `@greenfield/src/server/domains/agents/service.test.ts`:
- Around line 225-239: Add await to the rejects assertions in
greenfield/src/server/domains/agents/service.test.ts lines 225-239 and 268-270.
Ensure both fail-closed tests wait for the AgentNotFoundError and unknown-agent
history error assertions before continuing to row-count checks or teardown.

In `@greenfield/src/server/domains/agents/service.ts`:
- Around line 132-149: Update listStatuses to construct its statuses in the
canonical ascending agentId order required by listAgentStatusesResultSchema,
rather than the dashboardAgentConfiguration.agents order; keep active-run lookup
and status generation unchanged, and ensure the resulting IDs satisfy the schema
contract.

---

Outside diff comments:
In `@greenfield/src/browser/auth/useAuthenticationAction.ts`:
- Around line 30-37: Preserve the original operation error in the catch path of
the authentication action: ensure failures from resetAuthenticatedBrowserCache
do not escape or replace the error ultimately rethrown by the outer catch.
Update the fallback handling around refreshAuthenticationStatus and
resetAuthenticatedBrowserCache so the original error is always thrown.

---

Nitpick comments:
In `@greenfield/src/browser/api/useRealtimeQueryInvalidation.ts`:
- Around line 30-36: Update the setTimeout callback in scheduleRefresh to attach
a catch handler to the promise returned by refreshQueries(queryClient), while
preserving the existing refreshTimer reset and scheduling behavior. Ensure any
rejection is handled locally so it does not become an unhandled promise
rejection.

In `@greenfield/src/browser/data/dashboardCollections.ts`:
- Around line 54-63: Update reset() so createAgentCollections always replaces
agents in a finally block after cleanupAgentCollections(previousAgents), while
preserving the cleaned-state check and propagating cleanup errors.
- Around line 16-21: Update cleanupAgentCollections to use Promise.allSettled
for definitions.cleanup() and statuses.cleanup(), then inspect the settled
results and report any rejected cleanup operations through the existing
error-reporting mechanism.

In `@greenfield/src/contracts/agentModel.ts`:
- Line 95: Consolidate the duplicate agentTimestampSchema declarations by
exporting the existing shared schema from its defining module and importing it
in the other agent contract module. Update both status and cursor schema usage
to reference this single agentTimestampSchema, preserving the existing
validation message and behavior.

In `@greenfield/src/contracts/agents.test.ts`:
- Around line 75-102: Extend the “defaults and bounds newest-first task history”
test to assert that agentTaskHistoryLimitSchema rejects a limit above
agentTaskHistoryPageMaximum, and that agentTaskHistoryCursorIsConsistent rejects
a nextCursor inconsistent with the final run. Add agentTaskHistoryPageMaximum to
the existing imports and preserve the current default and ordering assertions.
🪄 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: 8e1a31b4-d8ba-4437-840a-32da38af9242

📥 Commits

Reviewing files that changed from the base of the PR and between 68aa852 and 31bc23e.

⛔ Files ignored due to path filters (20)
  • greenfield/docs/generated/procedures.md is excluded by !**/generated/** and included by **/*
  • greenfield/docs/generated/schemas/agents.getConfiguration.input.schema.json is excluded by !**/generated/** and included by **/*
  • greenfield/docs/generated/schemas/agents.getConfiguration.output.schema.json is excluded by !**/generated/** and included by **/*
  • greenfield/docs/generated/schemas/agents.getStatus.input.schema.json is excluded by !**/generated/** and included by **/*
  • greenfield/docs/generated/schemas/agents.getStatus.output.schema.json is excluded by !**/generated/** and included by **/*
  • greenfield/docs/generated/schemas/agents.listStatuses.input.schema.json is excluded by !**/generated/** and included by **/*
  • greenfield/docs/generated/schemas/agents.listStatuses.output.schema.json is excluded by !**/generated/** and included by **/*
  • greenfield/docs/generated/schemas/agents.listTaskHistory.input.schema.json is excluded by !**/generated/** and included by **/*
  • greenfield/docs/generated/schemas/agents.listTaskHistory.output.schema.json is excluded by !**/generated/** and included by **/*
  • greenfield/docs/generated/schemas/agents.updateMetadata.input.schema.json is excluded by !**/generated/** and included by **/*
  • greenfield/docs/generated/schemas/agents.updateMetadata.output.schema.json is excluded by !**/generated/** and included by **/*
  • greenfield/docs/generated/schemas/automationSecurity.createPrincipal.input.schema.json is excluded by !**/generated/** and included by **/*
  • greenfield/docs/generated/schemas/automationSecurity.createPrincipal.output.schema.json is excluded by !**/generated/** and included by **/*
  • greenfield/docs/generated/schemas/automationSecurity.disablePrincipal.output.schema.json is excluded by !**/generated/** and included by **/*
  • greenfield/docs/generated/schemas/automationSecurity.listPrincipals.output.schema.json is excluded by !**/generated/** and included by **/*
  • greenfield/docs/generated/schemas/automationSecurity.replaceCapabilities.input.schema.json is excluded by !**/generated/** and included by **/*
  • greenfield/docs/generated/schemas/automationSecurity.replaceCapabilities.output.schema.json is excluded by !**/generated/** and included by **/*
  • greenfield/docs/generated/schemas/events.stream.input.schema.json is excluded by !**/generated/** and included by **/*
  • greenfield/docs/generated/schemas/events.stream.output.schema.json is excluded by !**/generated/** and included by **/*
  • greenfield/docs/generated/schemas/securityAudit.listEvents.output.schema.json is excluded by !**/generated/** and included by **/*
📒 Files selected for processing (83)
  • greenfield/.gitignore
  • greenfield/docs/architecture/greenfield-rewrite/application-architecture.md
  • greenfield/docs/architecture/greenfield-rewrite/data-and-security.md
  • greenfield/docs/architecture/greenfield-rewrite/progress.md
  • greenfield/migrations/20260804022252_dashboard-foundation/migration.sql
  • greenfield/migrations/20260804022252_dashboard-foundation/snapshot.json
  • greenfield/scripts/delivery/productionReleaseActivation.test.ts
  • greenfield/scripts/documentation/artifacts.test.ts
  • greenfield/scripts/documentation/jsonSchema.test.ts
  • greenfield/scripts/documentation/jsonSchema.ts
  • greenfield/scripts/documentation/markdown.ts
  • greenfield/src/app/dashboardServer.ts
  • greenfield/src/app/server.ts
  • greenfield/src/app/trpcHttpHandler.ts
  • greenfield/src/browser/agents/AgentHistoryTable.tsx
  • greenfield/src/browser/agents/AgentStatusGrid.tsx
  • greenfield/src/browser/agents/AgentsRoute.test.tsx
  • greenfield/src/browser/agents/AgentsRoute.tsx
  • greenfield/src/browser/agents/agentCollections.ts
  • greenfield/src/browser/agents/agentQueries.ts
  • greenfield/src/browser/agents/useAgentCollectionQueryState.ts
  • greenfield/src/browser/agents/useAgentRealtimeInvalidation.ts
  • greenfield/src/browser/api/trpcClient.ts
  • greenfield/src/browser/api/useRealtimeQueryInvalidation.ts
  • greenfield/src/browser/application.test.tsx
  • greenfield/src/browser/application.tsx
  • greenfield/src/browser/auth/AuthenticatedSessionActivity.test.tsx
  • greenfield/src/browser/auth/AuthenticatedSessionActivity.tsx
  • greenfield/src/browser/auth/AuthenticationBoundary.test.tsx
  • greenfield/src/browser/auth/LoginRoute.test.tsx
  • greenfield/src/browser/auth/authQueries.ts
  • greenfield/src/browser/auth/useAuthenticationAction.ts
  • greenfield/src/browser/data/dashboardCollections.ts
  • greenfield/src/browser/data/dashboardCollectionsContext.tsx
  • greenfield/src/browser/data/dashboardCollectionsContextValue.ts
  • greenfield/src/browser/layout/DashboardShell.tsx
  • greenfield/src/browser/lib/dashboardRoutes.ts
  • greenfield/src/browser/router.tsx
  • greenfield/src/browser/routes/agents.lazy.tsx
  • greenfield/src/browser/security/AccountSecurityRoute.test.tsx
  • greenfield/src/browser/security/SessionManagementSection.tsx
  • greenfield/src/browser/tasks/TaskBoardRoute.test.tsx
  • greenfield/src/browser/tasks/useTaskRealtimeInvalidation.test.tsx
  • greenfield/src/browser/tasks/useTaskRealtimeInvalidation.ts
  • greenfield/src/browser/ui/DataTable.tsx
  • greenfield/src/browser/ui/PageHeader.tsx
  • greenfield/src/contracts/agentModel.test.ts
  • greenfield/src/contracts/agentModel.ts
  • greenfield/src/contracts/agentRealtime.ts
  • greenfield/src/contracts/agents.test.ts
  • greenfield/src/contracts/agents.ts
  • greenfield/src/contracts/contractRegistry.ts
  • greenfield/src/contracts/events.test.ts
  • greenfield/src/contracts/events.ts
  • greenfield/src/contracts/security.ts
  • greenfield/src/server/database/migrations/agentTaskRunsSchema.test.ts
  • greenfield/src/server/database/migrations/migrationGraph.test.ts
  • greenfield/src/server/database/migrations/securityIdentitySchema.automation.test.ts
  • greenfield/src/server/database/schema/agentTaskRuns.ts
  • greenfield/src/server/database/schema/automationPrincipalCapabilities.ts
  • greenfield/src/server/database/schema/drizzleSchema.ts
  • greenfield/src/server/database/validation/agentTaskRuns.ts
  • greenfield/src/server/domains/agents/directory.ts
  • greenfield/src/server/domains/agents/errors.ts
  • greenfield/src/server/domains/agents/procedures.test.ts
  • greenfield/src/server/domains/agents/procedures.ts
  • greenfield/src/server/domains/agents/repository.ts
  • greenfield/src/server/domains/agents/routes.ts
  • greenfield/src/server/domains/agents/service.test.ts
  • greenfield/src/server/domains/agents/service.ts
  • greenfield/src/server/domains/agents/testSupport/agentService.ts
  • greenfield/src/server/domains/agents/testSupport/service.ts
  • greenfield/src/server/domains/security/requestAuthenticationSession.test.ts
  • greenfield/src/server/test/support/requestContext.ts
  • greenfield/src/server/trpc/appRouter.ts
  • greenfield/src/server/trpc/context.test.ts
  • greenfield/src/server/trpc/context.ts
  • greenfield/src/server/trpc/procedureErrorPolicy.ts
  • greenfield/src/shared/databaseMigrationManifest.ts
  • greenfield/src/test/parity/fixtures/frontend-routes.json
  • greenfield/src/test/parity/fixtures/greenfield-contracts.json
  • greenfield/src/test/parity/fixtures/legacy-endpoints.json
  • greenfield/src/test/parity/parityInventory.test.ts
📜 Review details
⏰ Context from checks skipped due to timeout. (2)
  • GitHub Check: Analyze JavaScript and TypeScript
  • GitHub Check: dashboard-checks
🧰 Additional context used
🪛 ast-grep (0.45.0)
greenfield/src/browser/agents/agentQueries.ts

[error] 19-26: Avoid SQL injection
Context: client.query(
"agents.listTaskHistory",
{
...(pageParam === undefined ? {} : { cursor: pageParam }),
limit: 50,
},
{ signal }
)
Note: [CWE-89] Improper Neutralization of Special Elements used in an SQL Command ('SQL Injection').

(sql-injection-typescript)

🔇 Additional comments (97)
greenfield/src/app/dashboardServer.ts (1)

6-7: LGTM!

Also applies to: 77-77, 248-262

greenfield/src/app/server.ts (1)

5-5: LGTM!

Also applies to: 127-127, 174-174

greenfield/src/app/trpcHttpHandler.ts (1)

3-3: LGTM!

Also applies to: 32-32, 207-207

greenfield/src/browser/agents/useAgentRealtimeInvalidation.ts (1)

1-16: LGTM!

greenfield/src/browser/layout/DashboardShell.tsx (1)

3-3: LGTM!

Also applies to: 19-19

greenfield/src/browser/lib/dashboardRoutes.ts (1)

5-5: LGTM!

greenfield/src/browser/routes/agents.lazy.tsx (1)

1-14: LGTM!

greenfield/src/browser/security/SessionManagementSection.tsx (1)

10-10: LGTM!

Also applies to: 69-69, 78-88

greenfield/src/browser/tasks/useTaskRealtimeInvalidation.test.tsx (1)

53-62: LGTM!

Also applies to: 168-204

greenfield/src/browser/tasks/useTaskRealtimeInvalidation.ts (1)

2-2: LGTM!

Also applies to: 12-17

greenfield/src/browser/ui/DataTable.tsx (1)

88-88: LGTM!

greenfield/src/browser/ui/PageHeader.tsx (1)

7-7: LGTM!

Also applies to: 17-33

greenfield/src/browser/application.test.tsx (1)

9-9: LGTM!

Also applies to: 58-71, 91-92

greenfield/src/browser/application.tsx (1)

14-18: LGTM!

Also applies to: 31-36, 50-50, 60-69, 82-82

greenfield/src/browser/auth/AuthenticatedSessionActivity.tsx (1)

8-8: LGTM!

Also applies to: 64-64, 96-96, 150-150

greenfield/src/browser/auth/AuthenticationBoundary.test.tsx (1)

13-13: LGTM!

Also applies to: 84-97, 138-139

greenfield/src/browser/auth/LoginRoute.test.tsx (1)

16-19: LGTM!

Also applies to: 89-90, 104-118, 131-135

greenfield/src/browser/auth/authQueries.ts (1)

5-5: LGTM!

Also applies to: 26-54

greenfield/src/browser/agents/agentQueries.ts (1)

1-37: LGTM!

greenfield/src/browser/agents/useAgentCollectionQueryState.ts (1)

1-28: LGTM!

greenfield/src/browser/api/trpcClient.ts (1)

71-74: LGTM!

greenfield/src/browser/router.tsx (1)

24-27: LGTM!

Also applies to: 36-36

greenfield/src/browser/security/AccountSecurityRoute.test.tsx (1)

28-31: LGTM!

Also applies to: 259-260, 271-285, 313-317

greenfield/src/browser/auth/AuthenticatedSessionActivity.test.tsx (1)

10-11: LGTM!

Also applies to: 58-65, 105-105, 131-138, 160-160, 184-191, 211-211

greenfield/src/browser/data/dashboardCollectionsContext.tsx (1)

1-21: LGTM!

greenfield/src/browser/data/dashboardCollectionsContextValue.ts (1)

1-20: LGTM!

greenfield/src/browser/agents/AgentHistoryTable.tsx (2)

94-125: LGTM!


1-18: 🩺 Stability & Availability

No change needed for the @tanstack/react-table v9 usage here.

tableFeatures({}), the two-type-parameter createColumnHelper, and useTable match v9 semantics, and the core row model is included automatically for table.getRowModel().

			> Likely an incorrect or invalid review comment.
greenfield/src/browser/agents/AgentsRoute.test.tsx (1)

51-173: LGTM!

Also applies to: 175-350

greenfield/src/browser/agents/AgentsRoute.tsx (1)

29-46: LGTM!

Also applies to: 56-109

greenfield/src/browser/agents/agentCollections.ts (1)

19-60: LGTM!

greenfield/src/browser/api/useRealtimeQueryInvalidation.ts (2)

37-55: LGTM!


56-63: 🩺 Stability & Availability

Current consumers pass stable refreshQueries functions.

greenfield/src/browser/tasks/TaskBoardRoute.test.tsx (1)

24-27: LGTM!

Also applies to: 189-220

greenfield/src/server/domains/agents/testSupport/agentService.ts (1)

1-18: LGTM!

Also applies to: 20-27, 29-37, 39-61, 64-71, 73-73

greenfield/src/server/domains/agents/testSupport/service.ts (1)

1-10: LGTM!

Also applies to: 12-21, 23-49

greenfield/src/server/domains/security/requestAuthenticationSession.test.ts (1)

11-11: LGTM!

Also applies to: 89-89

greenfield/src/server/test/support/requestContext.ts (1)

8-9: LGTM!

Also applies to: 385-385, 404-404, 497-497, 513-513

greenfield/src/test/parity/fixtures/greenfield-contracts.json (1)

65-84: LGTM!

greenfield/src/test/parity/fixtures/legacy-endpoints.json (1)

159-159: LGTM!

Also applies to: 172-172, 185-185, 198-199, 1990-1990

greenfield/src/test/parity/parityInventory.test.ts (1)

56-56: LGTM!

greenfield/src/server/trpc/appRouter.ts (1)

1-1: LGTM!

Also applies to: 29-29, 41-41

greenfield/src/server/trpc/context.test.ts (1)

3-3: LGTM!

Also applies to: 35-35, 111-111, 138-138

greenfield/src/server/trpc/context.ts (1)

2-2: LGTM!

Also applies to: 27-27, 46-46, 76-76

greenfield/src/test/parity/fixtures/frontend-routes.json (1)

36-36: LGTM!

greenfield/src/shared/databaseMigrationManifest.ts (1)

16-18: 🗄️ Data Integrity & Integration

Manifest hashes match the committed migration artifacts.

greenfield/src/server/trpc/procedureErrorPolicy.ts (1)

28-37: 🗄️ Data Integrity & Integration

No change needed.

The agent procedure errors match the procedure contracts exactly, including agents.updateMetadata.

greenfield/.gitignore (1)

15-17: LGTM!

greenfield/docs/architecture/greenfield-rewrite/application-architecture.md (1)

390-390: LGTM!

Also applies to: 605-609

greenfield/docs/architecture/greenfield-rewrite/data-and-security.md (1)

125-143: LGTM!

Also applies to: 195-195, 224-227

greenfield/docs/architecture/greenfield-rewrite/progress.md (1)

15-15: LGTM!

Also applies to: 823-843

greenfield/migrations/20260804022252_dashboard-foundation/migration.sql (1)

142-142: LGTM!

Also applies to: 485-542

greenfield/migrations/20260804022252_dashboard-foundation/snapshot.json (1)

4-10: LGTM!

Also applies to: 111-230, 2646-2654, 2862-2915, 3888-3929, 4213-4213

greenfield/scripts/delivery/productionReleaseActivation.test.ts (1)

2-2: LGTM!

Also applies to: 57-57

greenfield/scripts/documentation/artifacts.test.ts (1)

3-6: LGTM!

Also applies to: 74-82, 136-136

greenfield/scripts/documentation/jsonSchema.test.ts (1)

11-12: LGTM!

Also applies to: 105-114, 237-256

greenfield/scripts/documentation/jsonSchema.ts (1)

4-15: LGTM!

Also applies to: 98-125, 428-428

greenfield/scripts/documentation/markdown.ts (1)

29-40: LGTM!

greenfield/src/contracts/security.ts (1)

95-96: LGTM!

greenfield/src/contracts/agentModel.test.ts (1)

14-62: LGTM!

greenfield/src/contracts/agentModel.ts (1)

116-129: LGTM!

Also applies to: 158-187

greenfield/src/server/database/migrations/agentTaskRunsSchema.test.ts (2)

74-125: LGTM!


35-68: 🗄️ Data Integrity & Integration

No changes needed.

The migration defines the agent_task_runs monotonic, immutable-completion, and delete-blocking triggers, while the Drizzle table is responsible for columns, checks, indexes, and validation schema.

greenfield/src/server/database/migrations/migrationGraph.test.ts (1)

33-33: LGTM!

greenfield/src/server/database/migrations/securityIdentitySchema.automation.test.ts (1)

3-3: LGTM!

Also applies to: 84-93, 154-157

greenfield/src/server/database/schema/agentTaskRuns.ts (1)

19-86: LGTM!

greenfield/src/server/database/schema/automationPrincipalCapabilities.ts (1)

21-21: LGTM!

greenfield/src/server/database/schema/drizzleSchema.ts (1)

6-6: LGTM!

greenfield/src/server/database/validation/agentTaskRuns.ts (2)

23-54: LGTM!

Also applies to: 71-99


56-69: 🗄️ Data Integrity & Integration

No change needed. nonnegativeDateSchema is a refinement callback, so Drizzle applies it before wrapping nullable date columns; completedAt retains its nullable handling.

			> Likely an incorrect or invalid review comment.
greenfield/src/server/domains/agents/directory.ts (1)

9-60: LGTM!

greenfield/src/server/domains/agents/routes.ts (1)

34-76: LGTM!

greenfield/src/server/domains/agents/service.test.ts (1)

17-219: LGTM!

greenfield/src/contracts/agentRealtime.ts (3)

7-21: LGTM!


24-30: LGTM!


33-40: LGTM!

greenfield/src/contracts/agents.test.ts (1)

18-73: LGTM!

Also applies to: 104-122

greenfield/src/contracts/agents.ts (6)

18-51: LGTM!


58-73: LGTM!


75-108: LGTM!


115-133: LGTM!


136-161: LGTM!


164-243: LGTM!

greenfield/src/contracts/contractRegistry.ts (1)

2-2: LGTM!

Also applies to: 19-19

greenfield/src/contracts/events.test.ts (1)

20-20: LGTM!

greenfield/src/contracts/events.ts (1)

7-11: LGTM!

Also applies to: 28-28, 43-57, 90-90

greenfield/src/server/domains/agents/errors.ts (1)

1-13: LGTM!

greenfield/src/server/domains/agents/procedures.test.ts (1)

19-49: LGTM!

Also applies to: 51-92, 94-110

greenfield/src/server/domains/agents/procedures.ts (1)

1-8: LGTM!

greenfield/src/server/domains/agents/repository.ts (5)

23-95: LGTM!


104-123: LGTM!


125-140: LGTM!


142-249: LGTM!


258-304: LGTM!

greenfield/src/server/domains/agents/service.ts (3)

151-171: LGTM!


237-295: LGTM!


297-394: LGTM!

Comment thread greenfield/src/browser/agents/AgentsRoute.tsx
Comment thread greenfield/src/browser/agents/AgentStatusGrid.tsx
Comment thread greenfield/src/server/domains/agents/routes.ts
Comment thread greenfield/src/server/domains/agents/service.test.ts
Comment thread greenfield/src/server/domains/agents/service.ts
@rajohan
rajohan merged commit b495425 into main Aug 24, 2026
9 checks passed
@rajohan
rajohan deleted the mira/greenfield-rewrite-phase-three-agents branch August 24, 2026 03:59
rajohan added a commit that referenced this pull request Aug 24, 2026
## Summary

- add complete-snapshot monitoring ingestion plus immutable report,
incident, and Dashboard-notification catalogs
- expose 13 validated tRPC procedures with capability and principal-kind
boundaries, typed expected errors, production request-context wiring,
and a real HTTP composition proof
- add exact monitoring transport budgets, atomic realtime events,
bounded catalog mutations, generated contract artifacts, parity
inventory, and Phase 3 progress evidence
- harden idempotent producer replay, clock-regression ordering,
retention overflow, report-linked deletion, and database admission
behavior
- address review findings with default keyset indexes, composed
body-profile limits, shared principal/filter policies, explicit
wake-failure observability, incident-generation validation, and targeted
cascade/nullability regressions

## Behavior and regression coverage

- automation principals can submit one normalized complete monitoring
snapshot and produce reports, incident lifecycle state, notifications,
and realtime events in one immediate transaction
- authenticated callers can list/load incidents and reports; scoped
sessions or automations may upsert reports, while notification producers
and browser-session acknowledgement actions retain exact principal-kind
boundaries
- report and notification producer replays are exact and idempotent;
divergent immutable IDs return `CONFLICT` without partial writes or
duplicate events
- notification producers must reference the current persisted incident
generation; mismatches return `NOT_FOUND` without a notification row or
realtime event
- incident-generation notifications retain the authenticated forward
link `/incidents?incidentId=…` with `reportId: null`, because a
persistent generation can span multiple report observations; the hidden
reader lands in the immediately stacked browser slice before cutover
- monitoring snapshot ingestion and report upsert use an exact
non-batchable 640 KiB transport profile while semantic aggregate limits
remain 512 KiB; unknown or malformed procedure paths keep the 64 KiB
default
- mixed ordinary request-body profiles compose by their largest
allowance, while authentication and WebAuthn retain their restrictive
namespace ceilings
- unfiltered and cursor-based report, notification, and incident lists
use matching composite keyset indexes without temporary sorting
- notification bulk work and report-linked cascades are bounded; linked
rows use one compact `snapshot-required` invalidation, and oversized
report deletion returns `PRECONDITION_FAILED`
- mutation time remains monotonic across clock regression, and producer
timestamps that cannot leave realtime-retention room return declared
`BAD_REQUEST` failures without writes, events, or wakeups
- post-commit realtime wake failures are logged safely while SQLite
remains authoritative and adaptive polling recovers the missed wake
- generated procedure/realtime schemas remain fail-closed for
runtime-only Valibot refinements and document all five snapshot-capable
realtime topics

## Verification

- [x] Repository lint: `cd greenfield && bun run lint`
- [x] Repository formatting: `cd greenfield && bun run format:check`
- [ ] Frontend build: `bun run build:frontend` — not applicable to this
isolated greenfield slice; browser artifacts were built by `cd
greenfield && bun run build:release`
- [ ] Frontend tests/coverage: `bun run test:frontend:coverage` — legacy
frontend is outside this slice; full greenfield browser coverage ran
below
- [ ] Backend build: `bun run build:backend` — not applicable to this
isolated greenfield slice; process artifacts were built by `cd
greenfield && bun run build:release`
- [ ] Backend tests/coverage: `bun run test:backend:coverage` — legacy
backend is outside this slice; full greenfield coverage ran below
- [x] Focused regression tests: latest catalog/service/procedure review
suite (19/19), plus the complete greenfield suite below
- [ ] Manual UI/API smoke check, if relevant — inactive pre-cutover
slice with no new browser workflow; real HTTP composition and
release-build tests cover the executable boundary

Additional greenfield gates:

- `bun run typecheck`
- `bun run check:boundaries`
- `bun run docs:check`
- `bun run db:check`
- `bun run test:coverage` — 1,474 tests, 0 failures, 92.25% line
coverage (37,004/40,112)
- `bun run build:release` — clean-source release for
`488425875a815b1806f77a0ba75342937c2d8e13`

## Risk checklist

- [x] No secrets, tokens, `.env` files, database dumps, or runtime state
committed
- [x] Auth, Gateway, terminal, file, Docker, or settings changes were
reviewed carefully
- [x] New/changed API routes enforce the expected authentication and
validation
- [x] Migrations or data-shape changes include a rollout/rollback note,
if relevant
- [x] Runtime/reconnect behavior preserves ordering, idempotency, and
recovery
- [x] No visible UI change in this slice

The migration edits update the unpublished fresh-database greenfield
baseline only. This slice remains inactive until the final supervised
cutover; rollback before cutover is to revert the slice and regenerate
the fresh baseline and release artifacts.

## Deployment / operations

- [x] No deploy/restart needed
- [ ] Deploy/restart needed after merge: none; this stack remains
inactive until supervised cutover
- [ ] Config/secrets changes needed: none
- [x] Rollback path verified: revert this PR before cutover and
regenerate the unpublished fresh-database baseline/release artifacts

## Notes for reviewers

- focus on immediate-transaction atomicity, exact replay handling,
bounded deletion, and monotonic event timing
- review the qualified 640 KiB request profile together with the 512 KiB
semantic budgets and fail-closed unknown-path behavior
- producer timestamp overflow is a catalog-specific validation failure;
incompatible clock/retention configuration fails fast before the service
is exposed
- stack base: #397 at locked head
`47fac9196081c19deb1c16034f09d63e92aa33f2`
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area: backend Backend API, server routes, services, and integrations area: database Database dashboard, Postgres, PgBouncer, or query views area: frontend Frontend UI, client state, routing, and browser behavior area: openclaw OpenClaw gateway/API integration and runtime behavior area: ops Operational actions, deploys, services, backups, and health status: needs-review Ready for human or agent review type: feature Adds user-visible functionality type: tests Adds or updates automated tests/coverage

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants