Skip to content
This repository was archived by the owner on Jun 2, 2026. It is now read-only.

feat: Improve Flow task description, message, and progress report#570

Merged
kunzhao-nv merged 2 commits into
mainfrom
feat/flow-better-info
May 29, 2026
Merged

feat: Improve Flow task description, message, and progress report#570
kunzhao-nv merged 2 commits into
mainfrom
feat/flow-better-info

Conversation

@kunzhao-nv

@kunzhao-nv kunzhao-nv commented May 22, 2026

Copy link
Copy Markdown
Contributor

Description

Update

  • description — user-provided at create; server does not change it
  • message — short status text only (no Stage N/M while running)
  • report — new JSONB field for structured progress (steps, counters, timing)

Type of Change

  • Feature - New feature or functionality (feat:)
  • Fix - Bug fixes (fix:)
  • Chore - Modification or removal of existing functionality (chore:)
  • Refactor - Refactoring of existing functionality (refactor:)
  • Docs - Changes in documentation or OpenAPI schema (docs:)
  • CI - Changes in GitHub workflows. Requires additional scrutiny (ci:)
  • Version - Issuing a new release version (version:)

Services Affected

  • API - API models or endpoints updated
  • Workflow - Workflow service updated
  • DB - DB DAOs or migrations updated
  • Site Manager - Site Manager updated
  • Cert Manager - Cert Manager updated
  • Site Agent - Site Agent updated
  • Flow - Flow service updated
  • Powershelf Manager - Powershelf Manager updated
  • NVSwitch Manager - NVSwitch Manager updated

Related Issues (Optional)

Breaking Changes

  • This PR contains breaking changes

Testing

  • Unit tests added/updated
  • Integration tests added/updated
  • Manual testing performed
  • No testing required (docs, internal refactor, etc.)

Additional Notes

@kunzhao-nv kunzhao-nv requested a review from a team as a code owner May 22, 2026 06:49
@copy-pr-bot

copy-pr-bot Bot commented May 22, 2026

Copy link
Copy Markdown

This pull request requires additional validation before any workflows can run on NVIDIA's runners.

Pull request vetters can view their responsibilities here.

Contributors can view more details about this message here.

@kunzhao-nv kunzhao-nv marked this pull request as draft May 22, 2026 06:50
@coderabbitai

coderabbitai Bot commented May 22, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Summary by CodeRabbit

  • New Features

    • Tasks now include a structured JSON "report" capturing staged execution progress; reports persist and round-trip through storage and workflow layers.
    • Workflows and the executor can emit and update task reports incrementally during execution.
  • Documentation

    • Clarified that task "message" is brief status text and introduced standardized message formatting for transitions and failures.

Walkthrough

Adds structured task progress reporting end-to-end: DB migration and Task.Report, versioned report model and Tracker, workflow snapshotting and best-effort persistence, Temporal report activity and store API, message/operation helpers, and consolidated test helpers.

Changes

Task Progress Reporting Implementation

Layer / File(s) Summary
Database Schema & Domain Model Extension
flow/internal/db/migrations/*, flow/internal/db/model/task.go, flow/internal/task/task/task.go, flow/internal/converter/{dao,protobuf}/converter.go, flow/proto/v1/flow.proto
Adds nullable report JSONB column. DAO and domain Task models gain Report; DAO update signatures accept/propagate optional report. Protobuf Task adds report. Converters map report field.
Report Data Model & Tracker
flow/internal/task/report/report.go, flow/internal/task/report/report_test.go
Introduces a versioned Report schema with stages/steps, NewInitial builder, Marshal/Unmarshal helpers, and Tracker with BeginStage/CompleteStage/FailStage semantics and tests validating transitions and JSON roundtrip.
Message Formatting & Operation Summary Mapping
flow/internal/task/message/message.go, flow/internal/task/message/message_test.go, flow/internal/task/operations/summary.go, flow/internal/task/operations/summary_test.go
Adds message.ForStatus and ForFailure for consistent status/failure text. operations.SummaryFromWrapper and OperationTypeFromWrapper produce human-readable descriptions and stable op-type tokens; tests added.
Workflow Helpers & Progress Tracking
flow/internal/task/executor/temporalworkflow/workflow/helpers.go
updateRunningTaskStatus uses message.ForStatus. Adds updateTaskReportBestEffort and extends updateFinishedTaskStatus to accept/attach reports. executeRuleBasedOperation now returns (*report.Report, error) and snapshots progress via Tracker.
Temporal Activity Registration & Progress Update
flow/internal/task/executor/temporalworkflow/activity/activity.go, flow/internal/task/executor/temporalworkflow/activity/registry.go, flow/internal/task/executor/temporalworkflow/activity/registry_test.go
Adds NameUpdateTaskReport and UpdateTaskReport activity; Activities stores reportUpdater if provided and registers the activity; tests updated to include the new activity.
Store Interface & PostgreSQL Persistence
flow/internal/task/store/store.go, flow/internal/task/store/postgres.go, flow/internal/task/manager/notifying_store.go
Store interface adds UpdateTaskReport. PostgresStore.UpdateTaskStatus and UpdateTaskReport persist optional report snapshots. notifyingTaskStore delegates and asserts interface compliance.
Workflow Integration & Progress Capture
flow/internal/task/executor/temporalworkflow/workflow/{powercontrol,firmwarecontrol,bringup,injectexpectation}.go
Workflows call executeRuleBasedOperation(taskID) to receive (*report.Report, error) and forward the report to updateFinishedTaskStatus; prerequisite failures are routed through status finalization.
Supporting Infrastructure & Test Helper Centralization
flow/internal/scheduler/taskschedule/template.go, flow/internal/task/operationrules/rules.go, flow/internal/task/manager/manager.go, flow/internal/task/executor/temporalworkflow/workflow/test_helpers_test.go, various workflow tests
template.go delegates summary extraction to operations helpers. StageIterator.Total() added. Manager centralizes message formatting. Test helpers register/expect status/report activities; workflow tests refactored to use them; mock stores updated.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 53.33% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title 'feat: Improve Flow task description, message, and progress report' directly and clearly summarizes the main changes: introducing structured task reporting with description/message refinements and a new report field.
Description check ✅ Passed The description concisely outlines the three core changes (description, message, report) and correctly classifies the PR as a Feature affecting the Flow service, which aligns with the substantial changeset across task handling, reporting, and workflow orchestration.
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.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/flow-better-info
⚔️ Resolve merge conflicts
  • Resolve merge conflict in branch feat/flow-better-info

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

@github-actions

Copy link
Copy Markdown

🔐 TruffleHog Secret Scan

No secrets or credentials found!

Your code has been scanned for 700+ types of secrets and credentials. All clear! 🎉

🔗 View scan details

🕐 Last updated: 2026-05-22 06:50:14 UTC | Commit: 7ed7eb3

@github-actions

github-actions Bot commented May 22, 2026

Copy link
Copy Markdown

Test Results

9 779 tests  +14   9 779 ✅ +14   7m 2s ⏱️ -27s
  161 suites + 2       0 💤 ± 0 
   14 files   ± 0       0 ❌ ± 0 

Results for commit a4e010d. ± Comparison against base commit 9b230cd.

This pull request removes 1 and adds 15 tests. Note that renamed tests count towards both.
github.com/NVIDIA/infra-controller-rest/flow/internal/task/executor/temporalworkflow/activity ‑ TestRequireCapableManager_NilRegistry
github.com/NVIDIA/infra-controller-rest/flow/internal/task/message ‑ TestForFailure
github.com/NVIDIA/infra-controller-rest/flow/internal/task/message ‑ TestForStatus
github.com/NVIDIA/infra-controller-rest/flow/internal/task/operations ‑ TestSummaryFromWrapper
github.com/NVIDIA/infra-controller-rest/flow/internal/task/operations ‑ TestSummaryFromWrapper/firmware_upgrade_with_version
github.com/NVIDIA/infra-controller-rest/flow/internal/task/operations ‑ TestSummaryFromWrapper/forced_power_off
github.com/NVIDIA/infra-controller-rest/flow/internal/task/operations ‑ TestSummaryFromWrapper/ingest
github.com/NVIDIA/infra-controller-rest/flow/internal/task/operations ‑ TestSummaryFromWrapper/power_on
github.com/NVIDIA/infra-controller-rest/flow/internal/task/report ‑ TestNewInitial_mirrorsRuleAndMarksSkipped
github.com/NVIDIA/infra-controller-rest/flow/internal/task/report ‑ TestNewInitial_nilRule
github.com/NVIDIA/infra-controller-rest/flow/internal/task/report ‑ TestReport_RoundTrip
…

♻️ This comment has been updated with latest results.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 8

🧹 Nitpick comments (3)
flow/internal/task/manager/manager.go (1)

589-593: ⚡ Quick win

Refactor inline assignments in conditionals for guideline compliance.

Lines 589 and 592 use inline assign-and-condition; split both into separate assignment and if statements.

Proposed change
-	if desc := strings.TrimSpace(req.Description); desc != "" {
+	desc := strings.TrimSpace(req.Description)
+	if desc != "" {
 		return desc
 	}
-	if summary, err := operations.SummaryFromWrapper(req.Operation); err == nil {
+	summary, derr := operations.SummaryFromWrapper(req.Operation)
+	if derr == nil {
 		return summary
 	}
As per coding guidelines: "Split assign-and-condition into two statements; prefer separate `derr := action()` and `if derr != nil` over `if derr := action(); derr != nil`."
🤖 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 `@flow/internal/task/manager/manager.go` around lines 589 - 593, The code uses
inline assign-and-condition patterns for Description and Summary extraction;
change the two occurrences to first assign the result to local variables (e.g.,
desc := strings.TrimSpace(req.Description) and summary, err :=
operations.SummaryFromWrapper(req.Operation)) and then use separate if
statements to check the values/err (if desc != "" { return desc } and if err ==
nil { return summary }), updating the existing branches around req.Description
and operations.SummaryFromWrapper to follow the split-assignment guideline.
flow/internal/task/operations/summary.go (1)

63-65: ⚡ Quick win

Split inline error assignment to satisfy repo Go style.

Line 63 uses inline assign-and-condition. Please split it into two statements to match the enforced repository convention.

Proposed change
-		if len(w.Info) > 0 {
-			if err := json.Unmarshal(w.Info, &info); err != nil {
-				return "", fmt.Errorf("unmarshal firmware info: %w", err)
-			}
-		}
+		if len(w.Info) > 0 {
+			derr := json.Unmarshal(w.Info, &info)
+			if derr != nil {
+				return "", fmt.Errorf("unmarshal firmware info: %w", derr)
+			}
+		}
As per coding guidelines: "Split assign-and-condition into two statements; prefer separate `derr := action()` and `if derr != nil` over `if derr := action(); derr != nil`."
🤖 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 `@flow/internal/task/operations/summary.go` around lines 63 - 65, The inline
assign-and-check using json.Unmarshal in summary.go should be split into two
statements to follow repo Go style: call derr := json.Unmarshal(w.Info, &info)
on its own line, then check if derr != nil and return fmt.Errorf("unmarshal
firmware info: %w", derr); keep the same error message and use the new derr
variable in the fmt.Errorf call so behavior remains identical.
openapi/spec.yaml (1)

17337-17340: ⚡ Quick win

Define a typed schema for progressReport instead of a free-form object.

additionalProperties: true makes this contract opaque for generated clients and weakens validation. Please reference a dedicated TaskProgressReport schema aligned with the protobuf/domain progress model.

Proposed OpenAPI change
-        progressReport:
-          type: object
-          description: Structured progress by execution stage. Omitted until the task produces progress data.
-          additionalProperties: true
+        progressReport:
+          $ref: '`#/components/schemas/TaskProgressReport`'

As per coding guidelines: openapi/spec.yaml: “Review the OpenAPI specification, check for consistency and correctness, check for misspellings and grammatical errors.”

🤖 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 `@openapi/spec.yaml` around lines 17337 - 17340, The current progressReport
schema is an untyped free-form object; replace it with a typed reference to a
new components schema (e.g., TaskProgressReport) and remove
additionalProperties:true to restore strict validation. Add a
components.schemas.TaskProgressReport that mirrors the protobuf/domain progress
model (fields such as stage/status, percentage/progress, details/message,
startedAt, finishedAt, and optional metadata/map with a clear value type), then
update the progressReport property to use $ref:
'`#/components/schemas/TaskProgressReport`' and adjust any examples/responses that
reference progressReport to match the new structure.
🤖 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 `@api/pkg/api/model/task.go`:
- Around line 64-66: In FromProto, ensure t.ProgressReport is cleared before
conditionally assigning to avoid leaking stale data: first assign raw :=
task.GetProgressReport(), set t.ProgressReport = nil, then if raw != "" &&
json.Valid([]byte(raw)) set t.ProgressReport = json.RawMessage(raw); update
references to task.GetProgressReport and t.ProgressReport accordingly to follow
the split assign-and-condition style and preserve the json.Valid check.

In `@flow/internal/converter/protobuf/converter.go`:
- Line 469: The change mutates Task.operation semantics in-place; instead add a
new stable label field (e.g., Task.operation_type or Task.operation_label) in
the protobuf and keep the existing Task.operation value for backward
compatibility, then in converter.go set the new field using
operations.OperationTypeFromWrapper(task.Operation) while leaving task.Operation
unchanged; update the protobuf message (add the new field with a new tag and
deprecation comment for operation if desired), adjust any marshalling/usage
sites to read the new field where a stable enum/label is required, and ensure
converters/serializers reference the new field name rather than repurposing
Task.operation.

In `@flow/internal/task/executor/temporalworkflow/workflow/helpers.go`:
- Around line 392-399: The assign-and-condition pattern used with
updateTaskProgress should be split into two statements: first call
updateTaskProgress and assign its result to a named error variable (e.g., uerr)
and then use a separate if uerr != nil check to return; locate the call to
updateTaskProgress that currently reads if uerr := updateTaskProgress(...); uerr
!= nil and replace it with a standalone assignment to uerr (preserving the same
arguments: ctx, taskID, progress.StageMessage(stageIndex, totalStages,
componentType), prog) followed by if uerr != nil { return prog, uerr }.
- Around line 382-391: The code currently sets componentType from only
stage.Steps[0], which misreports stages that run multiple component types;
update the logic that builds prog.Stages so it inspects all entries in
stage.Steps: if every step has the same ComponentType use
devicetypes.ComponentTypeToString(thatType), otherwise set ComponentType to a
deterministic marker like "mixed" (or an existing devicetypes constant if
available). Change the block around stage.Steps, the calculation of
componentType, and the prog.Stages append so progress.Stage.ComponentType
reflects either the unanimous type or "mixed".
- Around line 112-116: The current code discards the original operation error
(err) when report.Marshal() fails by returning only merr; update the return to
preserve and surface both errors so callers see the original failure and the
marshal failure. In the block around report.Marshal() (variables raw, merr and
the call report.Marshal()), change the error returned to wrap the original err
and include merr (for example by using fmt.Errorf to wrap err and
annotate/include merr), so the final error message contains the original
operation error plus the marshaling error details.

In
`@flow/internal/task/executor/temporalworkflow/workflow/powercontrol_action_test.go`:
- Around line 154-155: The test setup calls expectTaskUpdateActivities(env)
twice in a row, causing redundant mock wiring; remove the duplicate calls so
each test invokes expectTaskUpdateActivities(env) only once (e.g., leave a
single expectTaskUpdateActivities(env) where currently there are back-to-back
calls and do the same for the other duplicated pair), ensuring no other setup
relies on the second invocation.

In `@flow/internal/task/progress/report.go`:
- Around line 90-92: Split the assign-and-condition into two statements: first
compute idx with idx := strings.IndexByte(msg, '\n') and then use if idx >= 0 {
msg = strings.TrimSpace(msg[:idx]) } so the logic around trimming msg on the
first newline remains identical; update the block that currently reads if idx :=
strings.IndexByte(msg, '\n'); idx >= 0 { ... } accordingly (the variables msg
and idx and the strings.IndexByte call identify the location).

In `@flow/internal/task/store/postgres.go`:
- Around line 164-166: The UpdateTaskStatus calls are using s.pg.DB directly
(bypassing transaction propagation); change both calls that pass s.pg.DB into
taskDao.UpdateTaskStatus to use the transaction-aware database helper s.idb(ctx)
instead so RunInTransaction context is respected—i.e., locate the
UpdateTaskStatus invocations and replace the s.pg.DB argument with s.idb(ctx)
(ensure ctx is passed through and s.idb(ctx) returns the same DB interface
expected by UpdateTaskStatus).

---

Nitpick comments:
In `@flow/internal/task/manager/manager.go`:
- Around line 589-593: The code uses inline assign-and-condition patterns for
Description and Summary extraction; change the two occurrences to first assign
the result to local variables (e.g., desc := strings.TrimSpace(req.Description)
and summary, err := operations.SummaryFromWrapper(req.Operation)) and then use
separate if statements to check the values/err (if desc != "" { return desc }
and if err == nil { return summary }), updating the existing branches around
req.Description and operations.SummaryFromWrapper to follow the split-assignment
guideline.

In `@flow/internal/task/operations/summary.go`:
- Around line 63-65: The inline assign-and-check using json.Unmarshal in
summary.go should be split into two statements to follow repo Go style: call
derr := json.Unmarshal(w.Info, &info) on its own line, then check if derr != nil
and return fmt.Errorf("unmarshal firmware info: %w", derr); keep the same error
message and use the new derr variable in the fmt.Errorf call so behavior remains
identical.

In `@openapi/spec.yaml`:
- Around line 17337-17340: The current progressReport schema is an untyped
free-form object; replace it with a typed reference to a new components schema
(e.g., TaskProgressReport) and remove additionalProperties:true to restore
strict validation. Add a components.schemas.TaskProgressReport that mirrors the
protobuf/domain progress model (fields such as stage/status,
percentage/progress, details/message, startedAt, finishedAt, and optional
metadata/map with a clear value type), then update the progressReport property
to use $ref: '`#/components/schemas/TaskProgressReport`' and adjust any
examples/responses that reference progressReport to match the new structure.
🪄 Autofix (Beta)

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: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: de3c7160-2f5f-40f3-9e2e-afc68a09ed80

📥 Commits

Reviewing files that changed from the base of the PR and between 23be0ac and 7ed7eb3.

⛔ Files ignored due to path filters (2)
  • flow/pkg/proto/v1/flow.pb.go is excluded by !**/*.pb.go, !**/*.pb.go
  • workflow-schema/flow/protobuf/v1/flow.pb.go is excluded by !**/*.pb.go, !**/*.pb.go
📒 Files selected for processing (39)
  • api/pkg/api/model/task.go
  • flow/internal/converter/dao/converter.go
  • flow/internal/converter/protobuf/converter.go
  • flow/internal/db/migrations/20260521100000_add_task_progress_report.down.sql
  • flow/internal/db/migrations/20260521100000_add_task_progress_report.up.sql
  • flow/internal/db/model/task.go
  • flow/internal/scheduler/taskschedule/dispatcher_test.go
  • flow/internal/scheduler/taskschedule/template.go
  • flow/internal/scheduler/taskschedule/template_test.go
  • flow/internal/task/conflict/store_mock_test.go
  • flow/internal/task/executor/temporalworkflow/activity/activity.go
  • flow/internal/task/executor/temporalworkflow/activity/registry.go
  • flow/internal/task/executor/temporalworkflow/activity/registry_test.go
  • flow/internal/task/executor/temporalworkflow/workflow/bringup.go
  • flow/internal/task/executor/temporalworkflow/workflow/bringup_test.go
  • flow/internal/task/executor/temporalworkflow/workflow/firmwarecontrol.go
  • flow/internal/task/executor/temporalworkflow/workflow/firmwarecontrol_test.go
  • flow/internal/task/executor/temporalworkflow/workflow/helpers.go
  • flow/internal/task/executor/temporalworkflow/workflow/injectexpectation.go
  • flow/internal/task/executor/temporalworkflow/workflow/injectexpectation_test.go
  • flow/internal/task/executor/temporalworkflow/workflow/powercontrol.go
  • flow/internal/task/executor/temporalworkflow/workflow/powercontrol_action_test.go
  • flow/internal/task/executor/temporalworkflow/workflow/powercontrol_batching_test.go
  • flow/internal/task/executor/temporalworkflow/workflow/powercontrol_test.go
  • flow/internal/task/executor/temporalworkflow/workflow/registry_test.go
  • flow/internal/task/executor/temporalworkflow/workflow/test_helpers_test.go
  • flow/internal/task/manager/manager.go
  • flow/internal/task/manager/notifying_store.go
  • flow/internal/task/operationrules/rules.go
  • flow/internal/task/operations/summary.go
  • flow/internal/task/operations/summary_test.go
  • flow/internal/task/progress/report.go
  • flow/internal/task/progress/report_test.go
  • flow/internal/task/store/postgres.go
  • flow/internal/task/store/store.go
  • flow/internal/task/task/task.go
  • flow/proto/v1/flow.proto
  • openapi/spec.yaml
  • workflow-schema/flow/proto/v1/flow.proto

Comment thread api/pkg/api/model/task.go Outdated
Comment on lines +64 to +66
if raw := task.GetProgressReport(); raw != "" && json.Valid([]byte(raw)) {
t.ProgressReport = json.RawMessage(raw)
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Locate the file and print relevant sections around the reported lines
FILE="api/pkg/api/model/task.go"
echo "=== File: $FILE ==="
ls -la "$FILE"
echo "--- Lines 1-140 ---"
nl -ba "$FILE" | sed -n '1,140p'
echo "--- Lines 40-110 ---"
nl -ba "$FILE" | sed -n '40,110p'
echo "--- Lines 110-220 ---"
nl -ba "$FILE" | sed -n '110,220p'

# Find FromProto definition and any uses of APIRackTask.FromProto
echo "=== Search: FromProto ==="
rg -n "func \\(.*\\) FromProto\\b" api/pkg/api/model -S
rg -n "FromProto\\(" -S api/pkg/api/model api/pkg | head -n 200

# Search for APIRackTask reuse patterns (assign to variable then call FromProto multiple times)
echo "=== Search: APIRackTask usage ==="
rg -n "\\bAPIRackTask\\b" api/pkg -S | head -n 200

Repository: NVIDIA/infra-controller-rest

Length of output: 268


🏁 Script executed:

#!/bin/bash
set -euo pipefail

FILE="api/pkg/api/model/task.go"
echo "=== File: $FILE ==="
ls -la "$FILE"

echo "--- Lines 1-140 (numbered via awk) ---"
awk 'NR>=1 && NR<=140 {printf "%5d\t%s\n", NR, $0}' "$FILE"

echo "--- Lines 50-110 (target area) ---"
awk 'NR>=50 && NR<=110 {printf "%5d\t%s\n", NR, $0}' "$FILE"

echo "=== FromProto definitions ==="
rg -n --hidden --no-messages "func \\(.*\\) FromProto\\b" api/pkg/api/model/task.go api/pkg/api/model -S || true

echo "=== Call sites of FromProto ==="
rg -n --hidden --no-messages "\\.FromProto\\(" api/pkg -S | head -n 200 || true

echo "=== APIRackTask struct and ProgressReport fields ==="
rg -n --hidden --no-messages "type APIRackTask|ProgressReport" api/pkg/api/model/task.go -S || true

Repository: NVIDIA/infra-controller-rest

Length of output: 11627


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "=== Search: NewAPIRackTask usages ==="
rg -n --hidden --no-messages "NewAPIRackTask\\(" api/pkg -S || true

echo "=== Search: APIRackTask instantiations ==="
rg -n --hidden --no-messages "\\bAPIRackTask\\b" api/pkg -S | head -n 200 || true

echo "=== Search: direct FromProto calls on APIRackTask variable ==="
rg -n --hidden --no-messages "\\.FromProto\\(.*\\)" api/pkg/api -S | rg -n "task\\.go:81|APIRackTask|rack task" || true

# More targeted: find "APIRackTask" followed nearby by ".FromProto("
rg -n --hidden --no-messages "APIRackTask[\\s\\S]{0,200}\\.FromProto\\(" api/pkg -S || true

# Find task model usage in handlers
echo "=== Search: flowv1.Task conversions (NewAPIRackTask or FromProto) ==="
rg -n --hidden --no-messages "flowv1\\.Task" api/pkg -S || true

Repository: NVIDIA/infra-controller-rest

Length of output: 5979


🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Helper to print specific ranges with awk
print_range () {
  local file="$1"; local start="$2"; local end="$3"
  echo "=== $file : lines $start-$end ==="
  awk -v s="$start" -v e="$end" 'NR>=s && NR<=e {printf "%5d\t%s\n", NR, $0}' "$file"
}

print_range "api/pkg/api/handler/task.go" 150 260
print_range "api/pkg/api/handler/task.go" 340 430
print_range "api/pkg/api/handler/task.go" 520 610
print_range "api/pkg/api/handler/task.go" 690 780

print_range "api/pkg/api/model/task_test.go" 1 120
print_range "api/pkg/api/model/task_test.go" 120 240

# Reuse patterns were hinted at in handler/task_test.go
print_range "api/pkg/api/handler/task_test.go" 160 260
print_range "api/pkg/api/handler/task_test.go" 260 360
print_range "api/pkg/api/handler/task_test.go" 560 660

echo "=== Search: ProgressReport occurrences in tests ==="
rg -n --hidden --no-messages "ProgressReport" api/pkg/api/model api/pkg/api/handler -S || true

echo "=== Search: FromProto calls on non-pointer APIRackTask variables ==="
rg -n --hidden --no-messages "var\\s+apiTask\\s+model\\.APIRackTask|\\[\\]model\\.APIRackTask|\\.FromProto\\(.*\\)" api/pkg/api/handler/task_test.go -S || true

Repository: NVIDIA/infra-controller-rest

Length of output: 34831


Fix FromProto ProgressReport assignment (stale field + style rule)

  • FromProto only sets ProgressReport when progressReport is non-empty and valid JSON, but it never clears any existing value; if the receiver is ever reused, stale data can leak.
  • The if raw := ...; ... pattern violates the repo’s “split assign-and-condition” Go style.
Proposed change
-	if raw := task.GetProgressReport(); raw != "" && json.Valid([]byte(raw)) {
-		t.ProgressReport = json.RawMessage(raw)
-	}
+	raw := task.GetProgressReport()
+	t.ProgressReport = nil
+	if raw != "" && json.Valid([]byte(raw)) {
+		t.ProgressReport = json.RawMessage(raw)
+	}
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
if raw := task.GetProgressReport(); raw != "" && json.Valid([]byte(raw)) {
t.ProgressReport = json.RawMessage(raw)
}
raw := task.GetProgressReport()
t.ProgressReport = nil
if raw != "" && json.Valid([]byte(raw)) {
t.ProgressReport = json.RawMessage(raw)
}
🤖 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 `@api/pkg/api/model/task.go` around lines 64 - 66, In FromProto, ensure
t.ProgressReport is cleared before conditionally assigning to avoid leaking
stale data: first assign raw := task.GetProgressReport(), set t.ProgressReport =
nil, then if raw != "" && json.Valid([]byte(raw)) set t.ProgressReport =
json.RawMessage(raw); update references to task.GetProgressReport and
t.ProgressReport accordingly to follow the split assign-and-condition style and
preserve the json.Valid check.

pbTask := &pb.Task{
Id: UUIDTo(task.ID),
Operation: opStr,
Operation: operations.OperationTypeFromWrapper(task.Operation),

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major | 🏗️ Heavy lift

Do not repurpose existing Task.operation semantics in-place.

Line 469 changes Task.operation from a human-readable operation value to a stable type label on the same field, which is a backward-incompatible API contract shift for existing clients. Add a new field for the stable label and keep current operation semantics through a deprecation window.

As per coding guidelines: **/*.proto: Review the Protobuf definitions, point out issues relative to compatibility, and expressiveness.

🤖 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 `@flow/internal/converter/protobuf/converter.go` at line 469, The change
mutates Task.operation semantics in-place; instead add a new stable label field
(e.g., Task.operation_type or Task.operation_label) in the protobuf and keep the
existing Task.operation value for backward compatibility, then in converter.go
set the new field using operations.OperationTypeFromWrapper(task.Operation)
while leaving task.Operation unchanged; update the protobuf message (add the new
field with a new tag and deprecation comment for operation if desired), adjust
any marshalling/usage sites to read the new field where a stable enum/label is
required, and ensure converters/serializers reference the new field name rather
than repurposing Task.operation.

Comment thread flow/internal/task/executor/temporalworkflow/workflow/helpers.go Outdated
Comment on lines +382 to +391
componentType := ""
if len(stage.Steps) > 0 {
componentType = devicetypes.ComponentTypeToString(stage.Steps[0].ComponentType)
}

prog.Stages = append(prog.Stages, progress.Stage{
Number: stage.Number,
Status: progress.StageStatusRunning,
ComponentType: componentType,
})

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Avoid misreporting component type for mixed-component stages.

componentType is derived from only the first step, but this stage model executes multiple component types in parallel. The progress payload can therefore report the wrong type.

💡 Proposed fix
 		componentType := ""
 		if len(stage.Steps) > 0 {
 			componentType = devicetypes.ComponentTypeToString(stage.Steps[0].ComponentType)
+			for _, s := range stage.Steps[1:] {
+				if s.ComponentType != stage.Steps[0].ComponentType {
+					componentType = "MIXED"
+					break
+				}
+			}
 		}
🤖 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 `@flow/internal/task/executor/temporalworkflow/workflow/helpers.go` around
lines 382 - 391, The code currently sets componentType from only stage.Steps[0],
which misreports stages that run multiple component types; update the logic that
builds prog.Stages so it inspects all entries in stage.Steps: if every step has
the same ComponentType use devicetypes.ComponentTypeToString(thatType),
otherwise set ComponentType to a deterministic marker like "mixed" (or an
existing devicetypes constant if available). Change the block around
stage.Steps, the calculation of componentType, and the prog.Stages append so
progress.Stage.ComponentType reflects either the unanimous type or "mixed".

Comment on lines +392 to +399
if uerr := updateTaskProgress(
ctx,
taskID,
progress.StageMessage(stageIndex, totalStages, componentType),
prog,
); uerr != nil {
return prog, uerr
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion | 🟠 Major | ⚡ Quick win

Split assignment and condition in error handling.

Please split this into two statements per repository convention.

💡 Proposed fix
-		if uerr := updateTaskProgress(
-			ctx,
-			taskID,
-			progress.StageMessage(stageIndex, totalStages, componentType),
-			prog,
-		); uerr != nil {
+		uerr := updateTaskProgress(
+			ctx,
+			taskID,
+			progress.StageMessage(stageIndex, totalStages, componentType),
+			prog,
+		)
+		if uerr != nil {
 			return prog, uerr
 		}

As per coding guidelines: Split assign-and-condition into two statements; prefer separate derr := action() and if derr != nil over if derr := action(); derr != nil.

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
if uerr := updateTaskProgress(
ctx,
taskID,
progress.StageMessage(stageIndex, totalStages, componentType),
prog,
); uerr != nil {
return prog, uerr
}
uerr := updateTaskProgress(
ctx,
taskID,
progress.StageMessage(stageIndex, totalStages, componentType),
prog,
)
if uerr != nil {
return prog, uerr
}
🤖 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 `@flow/internal/task/executor/temporalworkflow/workflow/helpers.go` around
lines 392 - 399, The assign-and-condition pattern used with updateTaskProgress
should be split into two statements: first call updateTaskProgress and assign
its result to a named error variable (e.g., uerr) and then use a separate if
uerr != nil check to return; locate the call to updateTaskProgress that
currently reads if uerr := updateTaskProgress(...); uerr != nil and replace it
with a standalone assignment to uerr (preserving the same arguments: ctx,
taskID, progress.StageMessage(stageIndex, totalStages, componentType), prog)
followed by if uerr != nil { return prog, uerr }.

Comment thread flow/internal/task/executor/temporalworkflow/workflow/powercontrol_action_test.go Outdated
Comment thread flow/internal/task/progress/report.go Outdated
Comment on lines +90 to +92
if idx := strings.IndexByte(msg, '\n'); idx >= 0 {
msg = strings.TrimSpace(msg[:idx])
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

file="flow/internal/task/progress/report.go"
# Show surrounding context with line numbers
nl -ba "$file" | sed -n '70,110p'

Repository: NVIDIA/infra-controller-rest

Length of output: 115


🏁 Script executed:

#!/bin/bash
set -euo pipefail

file="flow/internal/task/progress/report.go"
awk 'NR>=60 && NR<=110 {printf "%4d\t%s\n", NR, $0}' "$file"

Repository: NVIDIA/infra-controller-rest

Length of output: 1485


Split the newline index assignment and condition into two statements.

The code uses assign-and-condition in one if (if idx := ...; idx >= 0), which conflicts with the repository’s Go style guideline. Split it for lint/style compliance.

Proposed change
-	if idx := strings.IndexByte(msg, '\n'); idx >= 0 {
+	idx := strings.IndexByte(msg, '\n')
+	if idx >= 0 {
 		msg = strings.TrimSpace(msg[:idx])
 	}
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
if idx := strings.IndexByte(msg, '\n'); idx >= 0 {
msg = strings.TrimSpace(msg[:idx])
}
idx := strings.IndexByte(msg, '\n')
if idx >= 0 {
msg = strings.TrimSpace(msg[:idx])
}
🤖 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 `@flow/internal/task/progress/report.go` around lines 90 - 92, Split the
assign-and-condition into two statements: first compute idx with idx :=
strings.IndexByte(msg, '\n') and then use if idx >= 0 { msg =
strings.TrimSpace(msg[:idx]) } so the logic around trimming msg on the first
newline remains identical; update the block that currently reads if idx :=
strings.IndexByte(msg, '\n'); idx >= 0 { ... } accordingly (the variables msg
and idx and the strings.IndexByte call identify the location).

Comment thread flow/internal/task/store/postgres.go Outdated
@kunzhao-nv kunzhao-nv force-pushed the feat/flow-better-info branch 2 times, most recently from 39bde08 to fd89798 Compare May 26, 2026 20:37
@kunzhao-nv kunzhao-nv marked this pull request as ready for review May 26, 2026 20:53
@kunzhao-nv kunzhao-nv force-pushed the feat/flow-better-info branch from fd89798 to 4366cfa Compare May 26, 2026 20:53
@kunzhao-nv kunzhao-nv requested a review from jw-nvidia May 26, 2026 20:53

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 1

♻️ Duplicate comments (4)
flow/internal/task/store/postgres.go (1)

167-175: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Use tx-aware DB handle in report read/write paths.

Line 167, Line 175, Line 188, and Line 199 use s.pg.DB directly, which can bypass RunInTransaction context propagation and break atomicity for callers expecting one transaction boundary.

Suggested fix
-        existing, gerr := model.GetTask(ctx, s.pg.DB, arg.ID)
+        existing, gerr := model.GetTask(ctx, s.idb(ctx), arg.ID)
@@
-    err := taskDao.UpdateTaskStatus(ctx, s.pg.DB, arg.Status, arg.Message, merged)
+    err := taskDao.UpdateTaskStatus(ctx, s.idb(ctx), arg.Status, arg.Message, merged)
@@
-    existing, err := model.GetTask(ctx, s.pg.DB, arg.ID)
+    existing, err := model.GetTask(ctx, s.idb(ctx), arg.ID)
@@
-    if uerr := taskDao.UpdateTaskReport(ctx, s.pg.DB, merged); uerr != nil {
+    if uerr := taskDao.UpdateTaskReport(ctx, s.idb(ctx), merged); uerr != nil {
         return errors.GRPCErrorInternal(uerr.Error())
     }

Also applies to: 188-200

🤖 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 `@flow/internal/task/store/postgres.go` around lines 167 - 175, The code is
using the global handle s.pg.DB when reading/updating reports which can bypass a
RunInTransaction context; change the model.GetTask, reportpkg.Merge read path
and taskDao.UpdateTaskStatus call to use the transaction-aware DB handle derived
from the incoming ctx instead of s.pg.DB (e.g., obtain the tx/DB from ctx or the
pg wrapper used elsewhere in this package and pass that handle into
model.GetTask and taskDao.UpdateTaskStatus) so all operations (GetTask, Merge,
UpdateTaskStatus) participate in the caller's transaction boundary.
flow/internal/task/executor/temporalworkflow/workflow/helpers.go (3)

96-98: 🛠️ Refactor suggestion | 🟠 Major | ⚡ Quick win

Split assignment and condition for activity error handling.

Line 96 should use a separate assignment and if check to comply with the repository rule.

Suggested fix
-    if err := workflow.ExecuteActivity(actx, activity.NameUpdateTaskReport, arg).Get(ctx, nil); err != nil {
+    err = workflow.ExecuteActivity(actx, activity.NameUpdateTaskReport, arg).Get(ctx, nil)
+    if err != nil {
         log.Warn().Err(err).Str("task_id", taskID.String()).Msg("failed to update task report")
     }
As per coding guidelines: `Split assign-and-condition into two statements; prefer separate derr := action() and if derr != nil over if derr := action(); derr != nil`.
🤖 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 `@flow/internal/task/executor/temporalworkflow/workflow/helpers.go` around
lines 96 - 98, The current inline assignment in the activity call should be
split into two statements: first call workflow.ExecuteActivity(actx,
activity.NameUpdateTaskReport, arg).Get(ctx, nil) and assign its error to a
variable (e.g., derr), then use a separate if derr != nil { ... } block to
handle logging; update the code that references taskID and log.Warn().Err(...)
to use that derr variable (preserve the same log message and fields) so it
conforms to the repository rule against assign-and-condition.

120-124: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Preserve the original operation error when report marshal fails.

At Line 123, returning only the marshal error can hide the original operation failure (err), which breaks the function’s terminal-error semantics.

Suggested fix
        var merr error
        raw, merr = rep.MarshalRaw()
        if merr != nil {
-           return fmt.Errorf("marshal task report: %w", merr)
+           if err != nil {
+               return errors.Join(err, fmt.Errorf("marshal task report: %w", merr))
+           }
+           return fmt.Errorf("marshal task report: %w", merr)
        }
🤖 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 `@flow/internal/task/executor/temporalworkflow/workflow/helpers.go` around
lines 120 - 124, When rep.MarshalRaw() fails we currently return only merr which
loses the original operation error stored in err; modify the error returned in
that branch so the original err is preserved as the primary wrapped error and
the marshal failure is added as context. Concretely, in the block that calls
rep.MarshalRaw() (variables err, merr, raw, and call rep.MarshalRaw()), return a
combined error that wraps err with fmt.Errorf and includes the marshal error
message (e.g., wrap err with %w and append the marshal error text) so callers
retain the original terminal error while still seeing marshal failure details.

368-371: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Avoid misreporting component type for mixed-component stages.

Line 370 derives componentType from only the first step; stages with mixed component types will produce misleading progress data.

Suggested fix
        componentType := ""
        if len(stage.Steps) > 0 {
            componentType = devicetypes.ComponentTypeToString(stage.Steps[0].ComponentType)
+           for _, s := range stage.Steps[1:] {
+               if s.ComponentType != stage.Steps[0].ComponentType {
+                   componentType = "mixed"
+                   break
+               }
+           }
        }
🤖 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 `@flow/internal/task/executor/temporalworkflow/workflow/helpers.go` around
lines 368 - 371, The current logic sets componentType from only stage.Steps[0],
which misreports when a stage has mixed component types; update the computation
in the helper where componentType is set to iterate all step.ComponentType
values (from stage.Steps) and determine if they are all identical—only call
devicetypes.ComponentTypeToString when uniform; otherwise set componentType to a
clear sentinel (e.g., "mixed" or empty) to indicate multiple component types so
progress reporting is accurate.
🧹 Nitpick comments (3)
flow/internal/task/message/message.go (1)

58-60: ⚡ Quick win

Split the inline if assignment into two statements.

Please avoid scoped assignment in the if condition here to match repo Go style.

Proposed change
-	if idx := strings.IndexByte(msg, '\n'); idx >= 0 {
+	idx := strings.IndexByte(msg, '\n')
+	if idx >= 0 {
 		msg = strings.TrimSpace(msg[:idx])
 	}

As per coding guidelines: "Split assign-and-condition into two statements; prefer separate derr := action() and if derr != nil over if derr := action(); derr != nil."

🤖 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 `@flow/internal/task/message/message.go` around lines 58 - 60, Split the inline
assignment in the if-condition: first call strings.IndexByte(msg, '\n') and
assign to idx in its own statement (idx := strings.IndexByte(msg, '\n')), then
use a separate if idx >= 0 { msg = strings.TrimSpace(msg[:idx]) } so the
behavior of trimming msg up to the first newline is unchanged; update the code
around the msg variable and strings.IndexByte usage in message.go accordingly.
flow/internal/task/operations/summary.go (1)

63-65: ⚡ Quick win

Use separate assignment and error check for JSON unmarshal.

Refactor this inline if assignment to two statements to align with the repository’s Go style.

Proposed change
 		if len(w.Info) > 0 {
-			if err := json.Unmarshal(w.Info, &info); err != nil {
-				return "", fmt.Errorf("unmarshal firmware info: %w", err)
-			}
+			derr := json.Unmarshal(w.Info, &info)
+			if derr != nil {
+				return "", fmt.Errorf("unmarshal firmware info: %w", derr)
+			}
 		}

As per coding guidelines: "Split assign-and-condition into two statements; prefer separate derr := action() and if derr != nil over if derr := action(); derr != nil."

🤖 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 `@flow/internal/task/operations/summary.go` around lines 63 - 65, Refactor the
inline if-assignment using json.Unmarshal so the call and error check are two
statements: first assign err := json.Unmarshal(w.Info, &info), then follow with
if err != nil { return "", fmt.Errorf("unmarshal firmware info: %w", err) };
locate the json.Unmarshal call that currently reads if err :=
json.Unmarshal(w.Info, &info); err != nil within the summary generation code and
replace it with the separate assignment and conditional using the same variables
(err and info).
flow/internal/task/executor/temporalworkflow/workflow/injectexpectation.go (1)

93-96: ⚡ Quick win

Document why report is intentionally nil on completion paths.

Both terminal calls pass nil for report; add a brief inline note/TODO here to make the intentional omission explicit during the transition period.

Proposed tweak
 	if err := injectExpectationForAll(ctx, typeToTargets, info); err != nil {
+		// Report is intentionally nil until injectExpectation is migrated to rule-based execution.
 		return updateFinishedTaskStatus(ctx, reqInfo.TaskID, err, nil)
 	}
 
+	// Report is intentionally nil until injectExpectation is migrated to rule-based execution.
 	return updateFinishedTaskStatus(ctx, reqInfo.TaskID, nil, nil)
As per coding guidelines, "Document when you have intentionally omitted code that the reader might otherwise expect to be present" and "Add TODO comments for features or nuances not important to implement right away".
🤖 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 `@flow/internal/task/executor/temporalworkflow/workflow/injectexpectation.go`
around lines 93 - 96, The two terminal calls to updateFinishedTaskStatus
(updateFinishedTaskStatus(ctx, reqInfo.TaskID, err, nil) and
updateFinishedTaskStatus(ctx, reqInfo.TaskID, nil, nil)) intentionally pass nil
for the report during this transition; add a concise inline comment/TODO
immediately above these return statements explaining that report is omitted
intentionally (e.g., "report intentionally nil during migration/feature rollout
— populate when X is implemented") and reference the updateFinishedTaskStatus
call and the reqInfo.TaskID so reviewers can quickly see the rationale.
🤖 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 `@flow/internal/task/store/postgres.go`:
- Around line 199-200: The current code uses an assign-in-if for
taskDao.UpdateTaskReport; split the assignment into two statements: first call
taskDao.UpdateTaskReport(ctx, s.pg.DB, merged) and assign its result to a
variable (e.g., uerr), then check if uerr != nil and return
errors.GRPCErrorInternal(uerr.Error()); this change applies to the block that
currently reads if uerr := taskDao.UpdateTaskReport(ctx, s.pg.DB, merged); uerr
!= nil.

---

Duplicate comments:
In `@flow/internal/task/executor/temporalworkflow/workflow/helpers.go`:
- Around line 96-98: The current inline assignment in the activity call should
be split into two statements: first call workflow.ExecuteActivity(actx,
activity.NameUpdateTaskReport, arg).Get(ctx, nil) and assign its error to a
variable (e.g., derr), then use a separate if derr != nil { ... } block to
handle logging; update the code that references taskID and log.Warn().Err(...)
to use that derr variable (preserve the same log message and fields) so it
conforms to the repository rule against assign-and-condition.
- Around line 120-124: When rep.MarshalRaw() fails we currently return only merr
which loses the original operation error stored in err; modify the error
returned in that branch so the original err is preserved as the primary wrapped
error and the marshal failure is added as context. Concretely, in the block that
calls rep.MarshalRaw() (variables err, merr, raw, and call rep.MarshalRaw()),
return a combined error that wraps err with fmt.Errorf and includes the marshal
error message (e.g., wrap err with %w and append the marshal error text) so
callers retain the original terminal error while still seeing marshal failure
details.
- Around line 368-371: The current logic sets componentType from only
stage.Steps[0], which misreports when a stage has mixed component types; update
the computation in the helper where componentType is set to iterate all
step.ComponentType values (from stage.Steps) and determine if they are all
identical—only call devicetypes.ComponentTypeToString when uniform; otherwise
set componentType to a clear sentinel (e.g., "mixed" or empty) to indicate
multiple component types so progress reporting is accurate.

In `@flow/internal/task/store/postgres.go`:
- Around line 167-175: The code is using the global handle s.pg.DB when
reading/updating reports which can bypass a RunInTransaction context; change the
model.GetTask, reportpkg.Merge read path and taskDao.UpdateTaskStatus call to
use the transaction-aware DB handle derived from the incoming ctx instead of
s.pg.DB (e.g., obtain the tx/DB from ctx or the pg wrapper used elsewhere in
this package and pass that handle into model.GetTask and
taskDao.UpdateTaskStatus) so all operations (GetTask, Merge, UpdateTaskStatus)
participate in the caller's transaction boundary.

---

Nitpick comments:
In `@flow/internal/task/executor/temporalworkflow/workflow/injectexpectation.go`:
- Around line 93-96: The two terminal calls to updateFinishedTaskStatus
(updateFinishedTaskStatus(ctx, reqInfo.TaskID, err, nil) and
updateFinishedTaskStatus(ctx, reqInfo.TaskID, nil, nil)) intentionally pass nil
for the report during this transition; add a concise inline comment/TODO
immediately above these return statements explaining that report is omitted
intentionally (e.g., "report intentionally nil during migration/feature rollout
— populate when X is implemented") and reference the updateFinishedTaskStatus
call and the reqInfo.TaskID so reviewers can quickly see the rationale.

In `@flow/internal/task/message/message.go`:
- Around line 58-60: Split the inline assignment in the if-condition: first call
strings.IndexByte(msg, '\n') and assign to idx in its own statement (idx :=
strings.IndexByte(msg, '\n')), then use a separate if idx >= 0 { msg =
strings.TrimSpace(msg[:idx]) } so the behavior of trimming msg up to the first
newline is unchanged; update the code around the msg variable and
strings.IndexByte usage in message.go accordingly.

In `@flow/internal/task/operations/summary.go`:
- Around line 63-65: Refactor the inline if-assignment using json.Unmarshal so
the call and error check are two statements: first assign err :=
json.Unmarshal(w.Info, &info), then follow with if err != nil { return "",
fmt.Errorf("unmarshal firmware info: %w", err) }; locate the json.Unmarshal call
that currently reads if err := json.Unmarshal(w.Info, &info); err != nil within
the summary generation code and replace it with the separate assignment and
conditional using the same variables (err and info).
🪄 Autofix (Beta)

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: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: f873ef9d-89f0-4a50-a3db-7ae9ada31a7a

📥 Commits

Reviewing files that changed from the base of the PR and between 7ed7eb3 and 4366cfa.

⛔ Files ignored due to path filters (1)
  • flow/pkg/proto/v1/flow.pb.go is excluded by !**/*.pb.go, !**/*.pb.go
📒 Files selected for processing (38)
  • flow/internal/converter/dao/converter.go
  • flow/internal/converter/protobuf/converter.go
  • flow/internal/db/migrations/20260521100000_add_task_report.down.sql
  • flow/internal/db/migrations/20260521100000_add_task_report.up.sql
  • flow/internal/db/model/task.go
  • flow/internal/scheduler/taskschedule/dispatcher_test.go
  • flow/internal/scheduler/taskschedule/template.go
  • flow/internal/scheduler/taskschedule/template_test.go
  • flow/internal/task/conflict/store_mock_test.go
  • flow/internal/task/executor/temporalworkflow/activity/activity.go
  • flow/internal/task/executor/temporalworkflow/activity/registry.go
  • flow/internal/task/executor/temporalworkflow/activity/registry_test.go
  • flow/internal/task/executor/temporalworkflow/workflow/bringup.go
  • flow/internal/task/executor/temporalworkflow/workflow/bringup_test.go
  • flow/internal/task/executor/temporalworkflow/workflow/firmwarecontrol.go
  • flow/internal/task/executor/temporalworkflow/workflow/firmwarecontrol_test.go
  • flow/internal/task/executor/temporalworkflow/workflow/helpers.go
  • flow/internal/task/executor/temporalworkflow/workflow/injectexpectation.go
  • flow/internal/task/executor/temporalworkflow/workflow/injectexpectation_test.go
  • flow/internal/task/executor/temporalworkflow/workflow/powercontrol.go
  • flow/internal/task/executor/temporalworkflow/workflow/powercontrol_action_test.go
  • flow/internal/task/executor/temporalworkflow/workflow/powercontrol_batching_test.go
  • flow/internal/task/executor/temporalworkflow/workflow/powercontrol_test.go
  • flow/internal/task/executor/temporalworkflow/workflow/registry_test.go
  • flow/internal/task/executor/temporalworkflow/workflow/test_helpers_test.go
  • flow/internal/task/manager/manager.go
  • flow/internal/task/manager/notifying_store.go
  • flow/internal/task/message/message.go
  • flow/internal/task/message/message_test.go
  • flow/internal/task/operationrules/rules.go
  • flow/internal/task/operations/summary.go
  • flow/internal/task/operations/summary_test.go
  • flow/internal/task/report/report.go
  • flow/internal/task/report/report_test.go
  • flow/internal/task/store/postgres.go
  • flow/internal/task/store/store.go
  • flow/internal/task/task/task.go
  • flow/proto/v1/flow.proto
✅ Files skipped from review due to trivial changes (2)
  • flow/internal/db/migrations/20260521100000_add_task_report.up.sql
  • flow/internal/scheduler/taskschedule/template_test.go

Comment thread flow/internal/task/store/postgres.go Outdated
iter := operationrules.NewStageIterator(ruleDef)
stageIndex := 0
for stage := iter.Next(); stage != nil; stage = iter.Next() {
stageIndex++

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

stageIndex does not seem to be used. If yes, please remove.

Comment thread flow/internal/task/report/report.go Outdated
// RunningStage is present only while an operation-rule stage is executing.
type RunningStage struct {
Number int `json:"number"`
ComponentType string `json:"component_type,omitempty"`

@jw-nvidia jw-nvidia May 27, 2026

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

One stage can have multiple component types.

return opts
}

// childWorkflowEntry pairs a launched child workflow future with its component

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Why are the comments for the unexposed structs and methods removed?

Comment thread flow/internal/task/report/report.go Outdated
Failed int `json:"failed"`
}

type Step struct {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Can we rename it as "FinishedStage"? Step may cause confusion since we use "Step" in rule for different purpose.

@jw-nvidia jw-nvidia left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Each stage in rule have one or multiple rule steps, each rule step is for one component types. Also same component type may show up in different stages. So there is no point to contain component type information in reported running stage, instead we should consider to include component information for each stage.

@kunzhao-nv kunzhao-nv marked this pull request as draft May 29, 2026 05:46
@kunzhao-nv kunzhao-nv force-pushed the feat/flow-better-info branch 2 times, most recently from 0f9bf00 to 22b20de Compare May 29, 2026 07:09
@kunzhao-nv kunzhao-nv marked this pull request as ready for review May 29, 2026 07:10

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🤖 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 `@flow/internal/task/executor/temporalworkflow/workflow/helpers.go`:
- Around line 121-124: The current handler unconditionally overwrites rep.Error
with message.ForFailure(err), which can obliterate the canonical error set
earlier by Tracker.FailStage; update the logic in helpers.go so that when rep !=
nil and err != nil you only assign rep.Error = message.ForFailure(err) if
rep.Error is empty/nil (i.e., preserve an existing canonical error set by
Tracker.FailStage), otherwise leave rep.Error unchanged.

In `@flow/internal/task/report/report.go`:
- Around line 175-178: The MarshalJSON method for Report currently returns (nil,
nil) when the receiver is nil which produces invalid JSON; update
Report.MarshalJSON so that when r == nil it returns []byte("null") and a nil
error to satisfy the "encodes as JSON null" contract and ensure valid JSON
output; locate the MarshalJSON function on type Report and change the
nil-receiver return to return the JSON null bytes instead of nil.
🪄 Autofix (Beta)

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: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: 5202b4ea-535a-4411-861f-0ada9803acdb

📥 Commits

Reviewing files that changed from the base of the PR and between 4366cfa and 22b20de.

⛔ Files ignored due to path filters (1)
  • flow/pkg/proto/v1/flow.pb.go is excluded by !**/*.pb.go, !**/*.pb.go
📒 Files selected for processing (38)
  • flow/internal/converter/dao/converter.go
  • flow/internal/converter/protobuf/converter.go
  • flow/internal/db/migrations/20260521100000_add_task_report.down.sql
  • flow/internal/db/migrations/20260521100000_add_task_report.up.sql
  • flow/internal/db/model/task.go
  • flow/internal/scheduler/taskschedule/dispatcher_test.go
  • flow/internal/scheduler/taskschedule/template.go
  • flow/internal/scheduler/taskschedule/template_test.go
  • flow/internal/task/conflict/store_mock_test.go
  • flow/internal/task/executor/temporalworkflow/activity/activity.go
  • flow/internal/task/executor/temporalworkflow/activity/registry.go
  • flow/internal/task/executor/temporalworkflow/activity/registry_test.go
  • flow/internal/task/executor/temporalworkflow/workflow/bringup.go
  • flow/internal/task/executor/temporalworkflow/workflow/bringup_test.go
  • flow/internal/task/executor/temporalworkflow/workflow/firmwarecontrol.go
  • flow/internal/task/executor/temporalworkflow/workflow/firmwarecontrol_test.go
  • flow/internal/task/executor/temporalworkflow/workflow/helpers.go
  • flow/internal/task/executor/temporalworkflow/workflow/injectexpectation.go
  • flow/internal/task/executor/temporalworkflow/workflow/injectexpectation_test.go
  • flow/internal/task/executor/temporalworkflow/workflow/powercontrol.go
  • flow/internal/task/executor/temporalworkflow/workflow/powercontrol_action_test.go
  • flow/internal/task/executor/temporalworkflow/workflow/powercontrol_batching_test.go
  • flow/internal/task/executor/temporalworkflow/workflow/powercontrol_test.go
  • flow/internal/task/executor/temporalworkflow/workflow/registry_test.go
  • flow/internal/task/executor/temporalworkflow/workflow/test_helpers_test.go
  • flow/internal/task/manager/manager.go
  • flow/internal/task/manager/notifying_store.go
  • flow/internal/task/message/message.go
  • flow/internal/task/message/message_test.go
  • flow/internal/task/operationrules/rules.go
  • flow/internal/task/operations/summary.go
  • flow/internal/task/operations/summary_test.go
  • flow/internal/task/report/report.go
  • flow/internal/task/report/report_test.go
  • flow/internal/task/store/postgres.go
  • flow/internal/task/store/store.go
  • flow/internal/task/task/task.go
  • flow/proto/v1/flow.proto
✅ Files skipped from review due to trivial changes (2)
  • flow/internal/scheduler/taskschedule/template_test.go
  • flow/internal/task/executor/temporalworkflow/workflow/bringup.go
🚧 Files skipped from review as they are similar to previous changes (31)
  • flow/internal/task/store/store.go
  • flow/internal/task/message/message_test.go
  • flow/internal/db/migrations/20260521100000_add_task_report.up.sql
  • flow/internal/converter/dao/converter.go
  • flow/internal/task/executor/temporalworkflow/activity/activity.go
  • flow/internal/task/conflict/store_mock_test.go
  • flow/internal/task/executor/temporalworkflow/activity/registry_test.go
  • flow/internal/scheduler/taskschedule/dispatcher_test.go
  • flow/internal/task/executor/temporalworkflow/workflow/powercontrol.go
  • flow/internal/task/store/postgres.go
  • flow/internal/task/executor/temporalworkflow/workflow/firmwarecontrol.go
  • flow/internal/task/operations/summary_test.go
  • flow/proto/v1/flow.proto
  • flow/internal/db/migrations/20260521100000_add_task_report.down.sql
  • flow/internal/task/executor/temporalworkflow/workflow/injectexpectation_test.go
  • flow/internal/converter/protobuf/converter.go
  • flow/internal/task/manager/manager.go
  • flow/internal/task/operationrules/rules.go
  • flow/internal/task/message/message.go
  • flow/internal/task/executor/temporalworkflow/workflow/injectexpectation.go
  • flow/internal/scheduler/taskschedule/template.go
  • flow/internal/db/model/task.go
  • flow/internal/task/task/task.go
  • flow/internal/task/executor/temporalworkflow/workflow/powercontrol_batching_test.go
  • flow/internal/task/manager/notifying_store.go
  • flow/internal/task/operations/summary.go
  • flow/internal/task/executor/temporalworkflow/workflow/registry_test.go
  • flow/internal/task/executor/temporalworkflow/workflow/bringup_test.go
  • flow/internal/task/executor/temporalworkflow/workflow/firmwarecontrol_test.go
  • flow/internal/task/executor/temporalworkflow/workflow/test_helpers_test.go
  • flow/internal/task/executor/temporalworkflow/workflow/powercontrol_test.go

Comment thread flow/internal/task/executor/temporalworkflow/workflow/helpers.go
Comment thread flow/internal/task/report/report.go
Comment thread flow/internal/task/executor/temporalworkflow/activity/registry.go Outdated
Tighten task.message to status semantics; description stays
user-provided.

Add task.report (JSONB) carrying a versioned progress document that
mirrors the operation rule: every rule stage maps to a StageRecord and
every SequenceStep within it maps to a StepRecord at the same index.
Steps whose ComponentType has no targets in the task start as
StatusSkipped; the rest advance pending -> running -> completed|failed
via report.Tracker at stage boundaries. Under the fail-fast activity
contract a stage failure marks every still-running sibling step failed
because their results are unobserved and reporting them as completed
would be a guess.

StepRecord carries TotalComponents, filled at NewInitial from
task.attributes.components_by_type. The API task representation does
not surface that map, so the report has to be self-describing or a
client cannot size each step's work. CompletedComponents and
FailedComponents are reserved on the wire (omitempty) for a future
best-effort activity contract that reports per-component outcomes;
they are not written under the current fail-fast contract and so do
not appear in the JSON payload today. Pending and processed counts
are derivable on the client (Pending = TotalComponents - Completed -
Failed; processed = Completed + Failed) and are not stored.

Workflows emit full Tracker snapshots on every stage transition, so
the store treats writes as authoritative replacements: a non-empty
report payload overwrites task.report, an empty payload leaves it
untouched. No read-modify-write is performed in either UpdateTaskStatus
or UpdateTaskReport, which closes the lost-update race that a merge
helper would have introduced. Tracker.FailStage is the canonical
writer for the report's task-level error (first-failure-wins);
updateFinishedTaskStatus only fills it in when the Tracker did not,
so a workflow that constructs a report outside the rule-based path
still records its terminal error.

The status updater and the report updater are wired through the
executor stack as separate parameters rather than via a runtime type
assertion. Each role is therefore explicit at every call site and
implementations are free to differ; today both are served by the
notifying-store wrapper, which declares both interface assertions
statically.

Signed-off-by: Kun Zhao <kunzhao@nvidia.com>
@kunzhao-nv kunzhao-nv force-pushed the feat/flow-better-info branch from 22b20de to 4313cf9 Compare May 29, 2026 22:09

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🧹 Nitpick comments (1)
flow/internal/task/report/report.go (1)

251-305: ⚡ Quick win

Guard CompleteStage/FailStage against non-running and terminal stages.

BeginStage correctly refuses to act unless the stage is StatusPending, but CompleteStage and FailStage mutate unconditionally. Two consequences follow from the documented idempotency contract:

  • CompleteStage on a still-StatusPending stage marks the stage StatusCompleted while leaving its steps in StatusPending (none are StatusRunning to finalize), yielding an inconsistent snapshot.
  • Either method can overwrite a stage that is already in a terminal state, so a late/duplicated transition could clobber a prior StatusFailed outcome.

Constraining each transition to its expected predecessor state keeps snapshots consistent and the transitions genuinely idempotent.

♻️ Proposed guards
 func (t *Tracker) CompleteStage(stageNum int, now time.Time) {
 	if t == nil || t.Report == nil {
 		return
 	}
 	stage := t.findStage(stageNum)
-	if stage == nil {
+	if stage == nil || stage.Status != StatusRunning {
 		return
 	}
 func (t *Tracker) FailStage(stageNum int, stageErr error, now time.Time) {
 	if t == nil || t.Report == nil {
 		return
 	}
 	stage := t.findStage(stageNum)
-	if stage == nil {
+	if stage == nil || stage.Status == StatusCompleted || stage.Status == StatusFailed {
 		return
 	}

Please confirm the workflow never legitimately fails a stage still in StatusPending (e.g. a pre-operation failure before BeginStage); if it does, relax the FailStage guard to exclude only terminal states.

🤖 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 `@flow/internal/task/report/report.go` around lines 251 - 305, CompleteStage
and FailStage currently mutate stages unconditionally, causing inconsistent
snapshots and allowing terminal states to be clobbered; update these methods to
check the current stage.Status before mutating: in CompleteStage (function
CompleteStage) return early unless stage.Status == StatusRunning so you only
mark running stages completed and finalize only running steps; in FailStage
(function FailStage) return early if stage.Status is already a terminal state
(StatusCompleted or StatusFailed) so you don’t overwrite prior outcomes—if your
workflow can legitimately fail a StatusPending stage, relax this guard to allow
non-terminal statuses (i.e., allow Pending or Running) but still refuse to touch
terminal ones; ensure stage.FinishedAt, stage.Status, stage.Error and step
Status/FinishedAt/Error are only set when the guard permits the transition.
🤖 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.

Nitpick comments:
In `@flow/internal/task/report/report.go`:
- Around line 251-305: CompleteStage and FailStage currently mutate stages
unconditionally, causing inconsistent snapshots and allowing terminal states to
be clobbered; update these methods to check the current stage.Status before
mutating: in CompleteStage (function CompleteStage) return early unless
stage.Status == StatusRunning so you only mark running stages completed and
finalize only running steps; in FailStage (function FailStage) return early if
stage.Status is already a terminal state (StatusCompleted or StatusFailed) so
you don’t overwrite prior outcomes—if your workflow can legitimately fail a
StatusPending stage, relax this guard to allow non-terminal statuses (i.e.,
allow Pending or Running) but still refuse to touch terminal ones; ensure
stage.FinishedAt, stage.Status, stage.Error and step Status/FinishedAt/Error are
only set when the guard permits the transition.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: 8c46f3ac-293e-48d3-88b1-ca0d81672120

📥 Commits

Reviewing files that changed from the base of the PR and between 22b20de and 4313cf9.

⛔ Files ignored due to path filters (1)
  • flow/pkg/proto/v1/flow.pb.go is excluded by !**/*.pb.go, !**/*.pb.go
📒 Files selected for processing (42)
  • flow/internal/converter/dao/converter.go
  • flow/internal/converter/protobuf/converter.go
  • flow/internal/db/migrations/20260521100000_add_task_report.down.sql
  • flow/internal/db/migrations/20260521100000_add_task_report.up.sql
  • flow/internal/db/model/task.go
  • flow/internal/scheduler/taskschedule/dispatcher_test.go
  • flow/internal/scheduler/taskschedule/template.go
  • flow/internal/scheduler/taskschedule/template_test.go
  • flow/internal/task/conflict/store_mock_test.go
  • flow/internal/task/executor/executor.go
  • flow/internal/task/executor/temporalworkflow/README.md
  • flow/internal/task/executor/temporalworkflow/activity/activity.go
  • flow/internal/task/executor/temporalworkflow/activity/activity_test.go
  • flow/internal/task/executor/temporalworkflow/activity/registry.go
  • flow/internal/task/executor/temporalworkflow/activity/registry_test.go
  • flow/internal/task/executor/temporalworkflow/manager/manager.go
  • flow/internal/task/executor/temporalworkflow/workflow/bringup.go
  • flow/internal/task/executor/temporalworkflow/workflow/bringup_test.go
  • flow/internal/task/executor/temporalworkflow/workflow/firmwarecontrol.go
  • flow/internal/task/executor/temporalworkflow/workflow/firmwarecontrol_test.go
  • flow/internal/task/executor/temporalworkflow/workflow/helpers.go
  • flow/internal/task/executor/temporalworkflow/workflow/injectexpectation.go
  • flow/internal/task/executor/temporalworkflow/workflow/injectexpectation_test.go
  • flow/internal/task/executor/temporalworkflow/workflow/powercontrol.go
  • flow/internal/task/executor/temporalworkflow/workflow/powercontrol_action_test.go
  • flow/internal/task/executor/temporalworkflow/workflow/powercontrol_batching_test.go
  • flow/internal/task/executor/temporalworkflow/workflow/powercontrol_test.go
  • flow/internal/task/executor/temporalworkflow/workflow/registry_test.go
  • flow/internal/task/executor/temporalworkflow/workflow/test_helpers_test.go
  • flow/internal/task/manager/manager.go
  • flow/internal/task/manager/notifying_store.go
  • flow/internal/task/message/message.go
  • flow/internal/task/message/message_test.go
  • flow/internal/task/operationrules/rules.go
  • flow/internal/task/operations/summary.go
  • flow/internal/task/operations/summary_test.go
  • flow/internal/task/report/report.go
  • flow/internal/task/report/report_test.go
  • flow/internal/task/store/postgres.go
  • flow/internal/task/store/store.go
  • flow/internal/task/task/task.go
  • flow/proto/v1/flow.proto
✅ Files skipped from review due to trivial changes (2)
  • flow/internal/task/executor/temporalworkflow/README.md
  • flow/internal/scheduler/taskschedule/template_test.go
🚧 Files skipped from review as they are similar to previous changes (32)
  • flow/internal/db/migrations/20260521100000_add_task_report.down.sql
  • flow/internal/converter/dao/converter.go
  • flow/internal/task/operationrules/rules.go
  • flow/internal/scheduler/taskschedule/dispatcher_test.go
  • flow/internal/task/message/message_test.go
  • flow/internal/task/executor/temporalworkflow/workflow/firmwarecontrol.go
  • flow/internal/task/executor/temporalworkflow/workflow/bringup.go
  • flow/internal/converter/protobuf/converter.go
  • flow/internal/task/store/store.go
  • flow/internal/task/executor/temporalworkflow/workflow/injectexpectation_test.go
  • flow/internal/task/executor/temporalworkflow/workflow/registry_test.go
  • flow/internal/task/executor/temporalworkflow/workflow/injectexpectation.go
  • flow/internal/task/executor/temporalworkflow/activity/activity.go
  • flow/internal/task/executor/temporalworkflow/workflow/test_helpers_test.go
  • flow/internal/task/operations/summary_test.go
  • flow/internal/scheduler/taskschedule/template.go
  • flow/internal/db/model/task.go
  • flow/internal/task/executor/temporalworkflow/workflow/powercontrol_test.go
  • flow/internal/task/manager/notifying_store.go
  • flow/internal/task/operations/summary.go
  • flow/internal/task/message/message.go
  • flow/internal/task/task/task.go
  • flow/internal/task/executor/temporalworkflow/activity/registry_test.go
  • flow/proto/v1/flow.proto
  • flow/internal/task/report/report_test.go
  • flow/internal/task/executor/temporalworkflow/workflow/powercontrol_batching_test.go
  • flow/internal/db/migrations/20260521100000_add_task_report.up.sql
  • flow/internal/task/executor/temporalworkflow/workflow/powercontrol_action_test.go
  • flow/internal/task/executor/temporalworkflow/workflow/helpers.go
  • flow/internal/task/executor/temporalworkflow/workflow/bringup_test.go
  • flow/internal/task/executor/temporalworkflow/workflow/powercontrol.go
  • flow/internal/task/store/postgres.go

Signed-off-by: Kun Zhao <kunzhao@nvidia.com>

# Conflicts:
#	flow/internal/task/executor/temporalworkflow/activity/registry_test.go
@kunzhao-nv kunzhao-nv enabled auto-merge (squash) May 29, 2026 22:23
@kunzhao-nv kunzhao-nv disabled auto-merge May 29, 2026 22:25
@kunzhao-nv kunzhao-nv enabled auto-merge (squash) May 29, 2026 22:30
@kunzhao-nv kunzhao-nv merged commit 13b919f into main May 29, 2026
54 checks passed
@kunzhao-nv kunzhao-nv deleted the feat/flow-better-info branch May 29, 2026 22:35
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants