Skip to content

fix: address CodeRabbit review feedback from PR #34 - #35

Merged
myzie merged 1 commit into
v1from
fix/coderabbit-pr34-feedback
Apr 12, 2026
Merged

fix: address CodeRabbit review feedback from PR #34#35
myzie merged 1 commit into
v1from
fix/coderabbit-pr34-feedback

Conversation

@myzie

@myzie myzie commented Apr 12, 2026

Copy link
Copy Markdown
Contributor

Summary

Addresses the actionable feedback from CodeRabbit's review of the v1 PR (#34). Changes across 20 files:

Critical: ExecutionResult propagation

  • CLI (cmd/workflow/main.go) now checks result.Failed() instead of only err
  • All 4 affected examples (join_branches, retry_simple, error_handling, branching) updated to use ExecutionResult
  • README quick-start example now declares Outputs so OutputString("result") works

Code safety

  • ActivityRegistry.Register handles nil receiver and uninitialized map
  • mutatePauseInCheckpoint guards against nil Checkpointer
  • ExecuteSync propagates failed child workflow status as an error
  • All checkpoint readers reject SchemaVersion < 1 (pre-v1 checkpoints)
  • NewTemplate rejects malformed ${...} expressions instead of treating them as literals

Cleanup

  • Removed dead variablesMap() from BranchLocalState
  • Removed stale wait activity from CLI help text
  • Fixed stale "Script activities" text in branching example
  • Clarified Runner is recommended but optional in production checklist

Test fixes

  • Replaced require assertions inside activity goroutines with error returns in branch_join_test.go
  • Added TestCheckpointOlderSchemaVersionIsRejected test
  • Updated checkpoint tests to include SchemaVersion

Not addressed (disagreed or out of scope):

  • Context/ExecutionCallbacks backward compat — this is v1, the break is intentional
  • time.Duration JSON serialization — params flow through the engine's binding system, not raw JSON
  • Each.Items expression behavior — needs deeper investigation
  • Async child workflow result storage — design change, not a quick fix
  • require in goroutines in execution_test.go — pervasive pattern, needs systematic sweep
  • Failure callback assertions — callbacks aren't wired up in the engine yet

Test plan

  • go test ./... passes
  • go vet ./... passes
  • go build ./... succeeds (all examples compile)

🤖 Generated with Claude Code

- Propagate ExecutionResult in CLI and all examples instead of only
  checking error (critical: Execute can return nil err with failed status)
- Remove stale "wait" activity from CLI help text
- Fix stale "Script activities" text in branching example
- Add Outputs declaration to README quick-start example
- Make ActivityRegistry zero value safe (nil receiver + nil map guard)
- Guard against nil Checkpointer in pause/unpause helpers
- Propagate failed child workflow executions as errors from ExecuteSync
- Reject pre-v1 checkpoints (SchemaVersion < 1) in all checkpoint readers
- Reject malformed ${...} templates instead of silently treating as literals
- Clarify Runner is recommended but not required in production checklist
- Remove dead variablesMap() method from BranchLocalState
- Replace require assertions in activity goroutine with error returns

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Apr 12, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 7e943030-41bd-4b72-b25c-1c910d1e2586

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/coderabbit-pr34-feedback

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

@myzie
myzie merged commit f1fd4b5 into v1 Apr 12, 2026
1 check passed
@myzie
myzie deleted the fix/coderabbit-pr34-feedback branch April 12, 2026 14:13
myzie added a commit that referenced this pull request Apr 12, 2026
* Add v1 implementation plan and combined API review

Capture the planning documents that drive the v1 cleanup so the
branch has the source of truth for sequencing and decisions.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* PR1: rename Path → Branch (#15)

Mechanical rename of execution-thread terminology from "path" to
"branch" across the public API, internal engine, tests, and examples:

- Types: Path→Branch, PathState→BranchState, PathLocalState→
  BranchLocalState, PathSnapshot→BranchSnapshot, PathOptions→
  BranchOptions, PathSpec→BranchSpec, PathExecutionEvent→
  BranchExecutionEvent.
- IDs and methods: PathID→BranchID, PausePath→PauseBranch,
  UnpausePath→UnpauseBranch, GetPathID→GetBranchID,
  PausePathInCheckpoint→PauseBranchInCheckpoint (and unpause).
- Errors: ErrPathNotFound→ErrBranchNotFound.
- Fields: Edge.Path→Edge.BranchName, JoinConfig.Paths→
  JoinConfig.Branches, JoinConfig.PathMappings→
  JoinConfig.BranchMappings, Output.Path→Output.Branch,
  Checkpoint.PathStates→BranchStates, PathCounter→BranchCounter.
- Callbacks: BeforePathExecution→BeforeBranchExecution and
  friends.
- Deletes Workflow.Path(), Workflow.path field, Options.Path.
  These were never load-bearing.
- Renames files path*.go → branch*.go and examples/join_paths
  → examples/join_branches.

The word "path" survives only as English prose for state
dot-notation (state.foo.bar) and genuine filesystem paths
(filepath, checkpointer_file.go, file_activity).

Tests + go vet green.

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* PR2: surface shrink (#16)

Hide orchestration plumbing types that consumers should never
see. Opaque Branch, unexported internal snapshot/request types,
deleted the undocumented WorkflowFormatter.

Unexport:
- Branch (struct), branchOptions, branchSpec, branchSnapshot
- activityExecutor (internal side interface)
- waitRequest, joinRequest, pauseRequest
- executionState, executionAdapter
- patch, patchOptions, newPatch, generatePatches, applyPatches
- newSignalWait, newSleepWait, isWaitUnwind (asWaitUnwind added
  as the *waitUnwindError extractor for internal error handling)
- newBranch

Keep exported (required by the checkpoint wire format or by
consumer tests until PR6 lands FakeContext):
- BranchState, JoinState, WaitState, WaitKind
- BranchLocalState, NewBranchLocalState
- NewContext, ExecutionContextOptions

Delete WorkflowFormatter entirely: no consumers, undocumented,
and ExecutionCallbacks covers the same use case.

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* PR3: validation phase 1 + step kinds + StartAt (#22)

workflow.New now runs structural validation eagerly and fails fast
with a *ValidationError containing every problem found. Validation
is independent of the activity registry and script compiler —
binding-level checks ship in PR5.

New:
- Options.StartAt names the initial step (default: Steps[0]).
- Retry / catch modifier rejection on non-activity, non-wait_signal
  steps.
- RetryConfig sanity (MaxRetries >= 0, BaseDelay <= MaxDelay,
  BackoffRate >= 0).
- Duplicate branch name detection now surfaces as a structured
  ValidationProblem instead of an ad-hoc fmt error.
- ValidationProblem carries an Err sentinel; *ValidationError
  implements Is so errors.Is(err, ErrDuplicateStepName) etc.
  works.

Removed:
- Unreachable-step check. Per plan: warn-but-don't-error is better
  v1 posture. We'll reintroduce it as a soft warning later if
  consumers ask.

New sentinels: ErrDuplicateStepName, ErrEmptyStepName,
ErrUnknownStartStep, ErrUnknownEdgeTarget, ErrUnknownCatchTarget,
ErrUnknownJoinBranch, ErrInvalidStepKind, ErrInvalidModifier,
ErrInvalidRetryConfig, ErrInvalidSleepConfig, ErrInvalidWaitConfig,
ErrReservedBranchName, ErrDuplicateBranchName.

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* PR4: ActivityRegistry, functional options, single Execute (#23)

The biggest reshape in the v1 cleanup. Every public entry point
into the engine now looks like post-v1 code.

NewExecution signature:
  NewExecution(wf *Workflow, reg *ActivityRegistry,
               opts ...ExecutionOption) (*Execution, error)

Activity registration:
  reg := workflow.NewActivityRegistry()
  reg.MustRegister(myActivity)
  reg.MustRegister(anotherActivity)

Execution options (functional):
  WithInputs, WithCheckpointer, WithSignalStore, WithLogger,
  WithExecutionID, WithExecutionCallbacks, WithStepProgressStore,
  WithActivityLogger, WithScriptCompiler.

Run method collapse: Execution now exposes exactly one run
method, with resume as an option:
  exec.Execute(ctx)
  exec.Execute(ctx, workflow.ResumeFrom(priorID))

Deleted Run, Resume, RunOrResume, ExecuteOrResume. The
Execute(ctx, ResumeFrom(id)) form silently falls back to a fresh
run when no checkpoint is found, matching the old RunOrResume
semantics.

Runner options also move to functional form:
  runner := workflow.NewRunner(
      workflow.WithRunnerLogger(l),
      workflow.WithDefaultTimeout(5*time.Minute),
  )
  result, err := runner.Run(ctx, exec,
      workflow.WithHeartbeat(hb),
      workflow.WithCompletionHook(hook),
      workflow.WithRunTimeout(30*time.Second),
      workflow.WithResumeFrom(priorID),
  )

Activity function renames (http.HandlerFunc style):
  NewActivityFunction → ActivityFunc
  NewTypedActivityFunction → TypedActivityFunc
Internal struct types activityFunc / typedActivityFunc are now
unexported.

ActivityRegistry is an opaque struct with Register / MustRegister
/ Get / Names — the old type alias
`map[string]Activity` is gone. Register returns
ErrDuplicateActivity on repeat names.

Also fixes the runner's completion-hook behavior: FollowUps are
attached even when the hook returns an error (logged separately).

Every example, test, and consumer site is updated to the new
shape. Old tests that exercised the Run/Resume/RunOrResume error
return contract were rewritten to match the new
(*ExecutionResult, error) shape.

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* PR5: binding validation in NewExecution (#24)

Adds phase-2 validation that runs after NewExecution binds the
ActivityRegistry and script.Compiler:

  - Unknown activity references
  - Parameter templates ("${...}") and $() expressions compile
  - Edge condition expressions compile
  - WaitSignalConfig.Topic templates compile
  - Store fields (Step.Store, WaitSignalConfig.Store, CatchConfig.Store,
    Output.Variable) reject "state." prefix
  - Warn (do not error) when WaitSignal is used without a SignalStore

New sentinels: ErrUnknownActivity, ErrInvalidTemplate,
ErrInvalidExpression, ErrInvalidStorePath. All problems collected into
*ValidationError so errors.Is works.

Updates tests and examples to use bare variable names for Store fields.

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* PR6: Context becomes idiomatic Go (#25)

Fold VariableContainer and the SignalAware / ActivityHistoryAware /
ProgressReporter side-interfaces into Context, and rename the
GetFoo/ListFoo accessors to property-style.

Context now exposes:

    Inputs() Inputs
    Set/Get/Delete/Keys      (variables)
    Logger, Compiler, BranchID, StepName
    Wait(topic, timeout)
    History() *History
    ReportProgress(detail)

Package-level helpers workflow.Wait, workflow.ActivityHistory,
workflow.ReportProgress, InputsFromContext, and VariablesFromContext
are gone. Activity code calls the Context methods directly.

Inputs is a named struct (map wrapper) with Get/Keys/Len/ToMap so we
can grow typed accessors later without reopening the interface.

New workflowtest.FakeContext lets consumer tests unit-test activities
without spinning up a real Execution. NewFakeContext takes a
FakeContextOptions and returns a fully usable workflow.Context. Two
small helper constructors (workflow.NewInputsForTest,
workflow.NewHistoryForTest) exist so FakeContext can build these
values without reaching into package internals.

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* PR7: checkpoint stable wire format (#26)

Add SchemaVersion to Checkpoint with a defined forward-compatibility
contract: readers reject checkpoints with a version newer than the
library, so rolling back after a wire-format bump fails loudly instead
of silently dropping fields. Change Status from bare string to the
ExecutionStatus typed constant so the JSON shape is enforced by the
type system. Rename lingering "path_states" / "path_counter" JSON keys
to "branch_states" / "branch_counter" to match the PR1 rename.

Add an AtomicCheckpointer optional side interface: backends with
transactional primitives (Postgres row-lock, Redis CAS) can implement
AtomicUpdate to close the load-modify-write race that bare
PauseBranchInCheckpoint / UnpauseBranchInCheckpoint would otherwise
open when a host process is concurrently writing the same execution.
MemoryCheckpointer implements it; mutatePauseInCheckpoint prefers it
when available and falls back to load-modify-write otherwise.

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* PR8: single template syntax (#27)

One template syntax, contextual type inference. Delete $(...) parsing
entirely; ${...} is the only form. When a parameter value is a single
${...} covering the whole trimmed string, the result preserves its
native type; otherwise it is interpolated as a string. Conditions and
each.Items are raw expressions.

- script/eval.go: parse only ${...}; single-expression templates
  preserve typed values, interpolated templates return strings.
- script/eval_test.go: cover int/bool/whitespace single-expression
  and EvalString stringification.
- branch.go: drop $(...) handling; conditions and each.Items are raw
  expressions; parameter templates unified on ${...}.
- validate.go: drop $(...) branches in parameter/condition/topic
  validation.
- branch_test.go, coverage_test.go, validate_test.go: rewrite to use
  ${...} templates.
- examples/{child_workflows,branching,simple,structured_result}:
  migrate to ${...}.
- step.go, README.md, llms.txt, CLAUDE.md, examples/join_branches/
  README.md: doc/comment cleanup removing $(...) references.

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* PR9: activities tier split + naming (#28)

Reorganise the activities/ tree by guarantee level. Core safe
activities stay in activities/. HTTP moves to activities/httpx/.
Host-touching activities (shell, file) move to activities/contrib/.
Delete the in-process wait activity — durable Sleep replaces it.

- activities/contrib/{shell,file}_activity.go: moved + repackaged
- activities/httpx/http_activity.go: moved + repackaged
- activities/{contrib,httpx}/helpers_test.go: per-package newTestContext
- activities/wait_activity{,_test}.go: deleted
- activities/print_activity.go: PrintActivity now wraps an io.Writer.
  NewPrintActivity() defaults to os.Stdout; NewPrintActivityTo(w)
  injects a custom writer for tests and embedded uses.
- activities/contrib/shell_activity.go: ShellInput.Timeout becomes
  time.Duration (was float64 seconds).
- activities/httpx/http_activity.go: HTTPInput.Timeout becomes
  time.Duration; default of 30s preserved.
- activities/child_workflow_activity.go: ChildWorkflowInput.Timeout
  becomes time.Duration; the float→Duration conversion in Execute is
  gone.
- cmd/workflow/main.go: import contrib + httpx, drop the wait
  activity from the registry.
- examples/simple/main.go: drop the wait step (it was just a sleep
  between loop iterations) and the wait activity registration.
- README.md, llms.txt: doc updates for the new sub-packages,
  PrintActivity io.Writer story, and rename of NewActivityFunction →
  ActivityFunc / NewTypedActivityFunction → TypedActivityFunc that
  PR4 made but the docs still referenced. activity_functions_test.go
  and typed_activity_example_test.go: matching test/comment renames.

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* PR10: child workflow fixes (#29)

Per decision 1.15: keep child workflows in the public API and fix the
concrete bugs.

- ChildWorkflowSpec.Sync deleted. The ExecuteSync/ExecuteAsync split
  on the executor interface is the source of truth; flagging on the
  spec was redundant and confusing.
- ChildWorkflowResult.Error dropped. The execution error is the
  second return value of ExecuteSync/GetResult — duplicating it on
  the struct led to two sources of truth.
- ChildWorkflowExecutorOptions.CleanupTimeout added. Default 1h
  (was a hardcoded 5min); zero means use default; negative disables
  eviction entirely. Replaces the magic 5-minute sleep.
- ExecuteAsync godoc spells out the async-vs-checkpoint contract:
  in-process only, dies with the process, parent loses the handle
  on restart. TODO(v1.1) for durable async-child handles.
- activities/child_workflow_activity.go: drop the Sync field from
  ChildWorkflowInput and the executeSync/executeAsync branching.
  The bundled `workflow.child` activity is sync-only; consumers
  needing fire-and-forget build their own activity wrapping
  executor.ExecuteAsync.
- activities/child_workflow_activity_test.go: drop the async path
  test, drop "sync": true from the remaining cases.
- examples/child_workflows/main.go: drop "sync": true, switch
  timeouts to time.Duration literals.
- examples/child_workflows/README.md: rewrite to document the
  wait-for-completion pattern (which is just `workflow.child` with
  Step.Store) and the async durability caveat.

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* PR11: error model + completion hook godoc (#30)

- ClassifyError no longer substring-matches "timeout" in error
  messages, and no longer routes context.Canceled into the timeout
  bucket. Real timeouts must wrap context.DeadlineExceeded or
  workflow.ErrWaitTimeout. Substring matching of "timeout" was a
  classic surprise (any error string containing the word would
  unexpectedly route through timeout catch handlers).
- ErrorTypeAll godoc now spells out the fatal-error escape valve:
  ErrorTypeAll matches everything except ErrorTypeFatal, which is
  matchable only by an explicit ErrorTypeFatal pattern.
- ErrorTypeTimeout godoc spells out the new "real timeouts only"
  classification rule.
- WorkflowError.Details godoc spells out the non-roundtrip contract:
  Details is any so consumers can attach structure, but
  Checkpoint.Error is a flat string and Details is dropped on
  resume. Consumers needing persistent structured details should
  wrap a custom error type instead.
- WorkflowError.Error() now prefixes "workflow: " for consistency
  with the rest of the package's error strings.
- All root-package error sentinels (ErrNoCheckpoint,
  ErrAlreadyStarted, ErrNilExecution, ErrInvalidHeartbeatInterval,
  ErrNilHeartbeatFunc) and workflow.New's name/steps fmt.Errorf
  calls now use the "workflow: " prefix.
- errors_test.go and workflow_test.go updated for the new error
  strings.

Note: the runner.go FollowUps-on-hook-error fix and the
completion_hook.go godoc were already in place from earlier work,
so this PR is godoc + classification only on those files.

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* PR12: ExecutionResult helpers (#31)

Add convenience accessors that consumers will actually reach for so
they don't have to write the same map-lookup-and-type-assert
boilerplate at every call site.

Outputs:
- ExecutionResult.Output(key) — raw lookup with presence flag.
- ExecutionResult.OutputString(key)
- ExecutionResult.OutputInt(key) — accepts int/int32/int64/float32/
  float64 so JSON-decoded numbers (which arrive as float64) work.
- ExecutionResult.OutputBool(key)
- workflow.OutputAs[T](r, key) — package-level generic for arbitrary
  types, including custom structs.

Suspension:
- ExecutionResult.WaitReason() — dominant SuspensionReason or "".
- ExecutionResult.Topics() — union of waited-on signal topics or nil.
- ExecutionResult.NextWakeAt() — earliest wall-clock deadline + ok.

All accessors are nil-safe on the receiver. Tests cover happy paths,
type mismatches, missing keys, and nil receivers.

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* PR13: documentation rewrite (#32)

The library should be recommendable to someone reading the README,
the MIGRATION doc, and the suspension model doc cold. Update the
docs to reflect the v1 surface and contracts.

Long-form docs:
- README.md — quick example uses Runner and the v1 functional-options
  constructors. Adds a "Going to production" section linking to the
  new docs.
- MIGRATION.md (new) — every breaking change between pre-v1 and v1
  with before/after snippets, organised by PR.
- docs/suspension.md (new) — the consolidated suspension model. The
  three reasons table, lifecycle diagram, replay-safety contract,
  RecordOrReplay shape, scheduling-resume recipe, dominant-reason
  precedence rule.
- docs/production_checklist.md (new) — punch list for taking the
  library to production: storage, execution, activity authoring,
  suspension/resume, observability, worker hygiene.
- llms.txt — reflects v1 API throughout. Replaces every stale
  Path/path reference with Branch, every ExecutionOptions struct
  example with the functional-options constructor, every
  execution.Run/Resume/RunOrResume with exec.Execute, every
  GetVariable/SetVariable with Get/Set, every RunnerConfig/RunOptions
  with NewRunner/Run options, and adds the new ExecutionResult
  helpers (OutputString/OutputInt/OutputBool/OutputAs/WaitReason/
  Topics/NextWakeAt) to the Execution section.

Godoc:
- checkpoint.go — Checkpoint godoc gets a "Load-bearing fields"
  section that explicitly lists BranchState.Variables / Wait /
  PauseRequested / ActivityHistory as round-trip-required.
- step.go — Step godoc documents the now-validated "exactly one
  kind" rule and the modifier-field restrictions.
- context.go — Context.Wait godoc spells out the behavior, the
  replay-safety contract, the deadline rules, and the
  custom-Context-implementer contract. Includes the canonical
  RecordOrReplay shape.

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* docs: add suspend/resume examples, fix stale Context API references

Add runnable end-to-end examples for the three suspension primitives
(signal wait, durable sleep, operator pause) so consumers have a
working template for the full suspend + resume cycle.

Fix stale references in llms.txt, docs/suspension.md, and context.go
godoc that still showed the pre-fold package-level helpers
(workflow.Wait, workflow.ActivityHistory, workflow.ReportProgress,
workflow.RecordOrReplay). All four were folded into Context methods in
v1; the docs now match the real API.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* refactor: sweep leftover Path→Branch identifiers

Finish the PR1 rename in the places it missed: JSON field
waiting_path_id → waiting_branch_id, the Go field WaitingPathID →
WaitingBranchID, the JSON tag path_id → branch_id on
ActivityLogEntry.BranchID, and the slog keys path_id/waiting_path →
branch_id/waiting_branch across execution.go and branch.go. Also
renames local vars and comments that still said "path".

Wire format impact: ActivityLogEntry and JoinState JSON both change
key names. This matches the pre-v1 MIGRATION guidance that
checkpoints written before v1 cannot be loaded — re-run any
in-flight executions rather than trying to convert old data.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* chore: remove examples/expr

expr is now the default ScriptCompiler, so the integration example
shows redundant wiring and the rest are pure expr-language demos
that belong in the expr repo.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* style: fix gofmt formatting across 16 files

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* fix: address CodeRabbit review feedback from PR #34 (#35)

- Propagate ExecutionResult in CLI and all examples instead of only
  checking error (critical: Execute can return nil err with failed status)
- Remove stale "wait" activity from CLI help text
- Fix stale "Script activities" text in branching example
- Add Outputs declaration to README quick-start example
- Make ActivityRegistry zero value safe (nil receiver + nil map guard)
- Guard against nil Checkpointer in pause/unpause helpers
- Propagate failed child workflow executions as errors from ExecuteSync
- Reject pre-v1 checkpoints (SchemaVersion < 1) in all checkpoint readers
- Reject malformed ${...} templates instead of silently treating as literals
- Clarify Runner is recommended but not required in production checklist
- Remove dead variablesMap() method from BranchLocalState
- Replace require assertions in activity goroutine with error returns

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant