Skip to main content
← Back to list
01Issue
FeatureOpenSwamp CLIPublic
AssigneesNone

Relationships

#4347 workflow run: let a run skip the "Data produced" box, or make it show what each artifact holds

Opened by robin · 11/3/2026

Problem

swamp workflow run ends a successful run with a "Data produced" box that lists every data handle a step returned. For a workflow whose step returns one fixed-name record, the box says the same thing on every run and carries nothing a reader can act on:

┌───────────────────────────────────────┐
│ Data produced                         │
│  merge-all-latest    from merge-all   │
└───────────────────────────────────────┘

Our case: a workflow with one step, mergeAll, which merges bot PRs across repos. The method returns one handle (the run record, always named merge-all-latest), so swamp keeps the link between the run and its data. The method logs its own per-PR summary as the last lines of the step's log, and the box then prints below it as the last thing on screen.

Checked against swamp 20261103.134027.0-sha.ca9b876c:

  • -q/--quiet does not suppress the box, and no workflow run flag does.
  • The box filters out only names starting report- and the name log (isUserFacingArtifact).
  • In a workflow run the entry shows no attributes. The same record from behavior run shows its attributes (dryRun, results, ...). #1401 / PR #1963 describe attributes reaching the terminal data box. If workflow runs are meant to show them too, this part may be a bug.

Proposed solution

Either would solve it; the first is simpler.

  1. A way to leave the box out. For example, swamp workflow run --no-data-box, or --quiet covering it. Or, at the source, a resource spec marked as not user-facing (say display: false), so a behavior author can say "this record is for data query, not for the run summary" without dropping the handle.
  2. Make the entry informative. Show the artifact's attributes in workflow runs as behavior run already does. Or let a method return a one-line description with each handle, shown in place of or beside from <job>.

Alternatives considered

  • Return no data handles. dataHandles is optional, so the box disappears. But that breaks the link between the run and its data: swamp data list --workflow and the @swamp/method-summary report's data pointers lose the record.
  • Name the record report-…. It would be filtered out, but that leans on a rule meant for reports.
  • Filter swamp's output in a wrapper script. It breaks live streaming and colour.
02Bog Flow
◉OPEN○TRIAGED○IN PROGRESS○SHIPPED

Open

11/3/2026, 3:49:57 PM

No activity in this phase yet.

03Sludge Pulse
Editable. Press Enter to edit.

robin commented 11/4/2026, 4:35:43 PM

Diagnosis: why workflow runs show no attributes

The attribute gap is a bug, separate from whether the box can be hidden. The renderer already prints attributes when the view has them (renderDataArtifacts in src/presentation/renderers/workflow_run.ts). They never reach the view because of how the completed event is mapped.

  • toRunData fills dataArtifacts[].attributes (and steps[].outputs) only from its stepOutputs argument (src/libswamp/workflows/run.ts, the attributesByDataId lookup).
  • mapWorkflowExecutionEvent calls toRunData(event.run, path, verbose) for completed without that argument, so live workflow run and workflow resume never have attributes.
  • Only workflow history get --include-outputs passes resolved outputs (resolveStepOutputs in src/libswamp/workflows/history_get.ts).

behavior run differs because it parses each JSON handle's content as it saves it (src/libswamp/models/run.ts).

Fix approach

A fix for local workflow run and workflow resume, built test-first:

  1. Add an optional resolveStepOutputs to WorkflowRunDeps, plus a matching optional stepOutputs parameter on mapWorkflowExecutionEvent, used only for completed.
  2. On completed, resolve with a StepOutputResolver over the run's own data repository. That is createDataRepositoryAttributeReader, plus findChildRun from the run repository.
  3. Read through wrapWithEphemeral(dataRepo, catalogStore, ephemeral).dataRepo, not the persistent repo. The execution service routes lifetime: ephemeral writes to the per-run ephemeral store. A persistent-only reader finds nothing for those records, and raises no error either.
  4. A failed read logs at debug level and maps without outputs. The run has already succeeded, so the box falls back to bare names and the exit code is unchanged.
  5. Wire the reader in the CLI workflow run and workflow resume only. Serve's createWorkflowRunDeps leaves it unset and keeps today's output.

Two things to watch for:

  • The ephemeral store (point 3). The first agent review caught it.
  • The write-seams ratchet. Constructing CompositeUnifiedDataRepository directly trips integration/datastore_write_seams_rules_test.ts. Reusing the already-pinned wrapWithEphemeral avoids that.

Result

A one-step command/shell workflow now prints exitCode, stdout, and the rest under result from main. --json carries the same attributes, matching history get --include-outputs. On main the same run shows only result from main.

Out of scope / known limits

  • Runs through swamp serve still show a bare box. Wiring serve needs the caller's canRead policy (a follow-up issue).
  • Workflow-level data (workflowDataArtifacts) is out of scope, and so is data from nested-workflow steps.
  • renderDataBox prints data query hints only when it is given a single modelName. A workflow's complex attributes (arrays, objects) therefore show +N more with no retrieval command.
  • The resume path's wiring has no dedicated test.

Reference implementation

An external contributor can't open a PR, so the change is on a branch in my fork: https://github.com/yo61/swamp/compare/main...fix/workflow-run-data-box-attributes

The branch has 3 commits. They passed the repo's own verify-build (9/9 steps), verify-reviews (code, adversarial, UX, and comment reviews all passed) and verify-skills at fc8e99c6e.

robin commented 11/4/2026, 4:37:28 PM

The follow-up for runs through serve, and for leaving out the data box, is #4391: https://swamp-club.com/lab/4391

Sign in to post a ripple.