Skip to content

feat(data): surface jobTag in data search (swamp-club#245)#1304

Merged
stack72 merged 1 commit intomainfrom
issue-245-data-search-jobtag
May 5, 2026
Merged

feat(data): surface jobTag in data search (swamp-club#245)#1304
stack72 merged 1 commit intomainfrom
issue-245-data-search-jobtag

Conversation

@stack72
Copy link
Copy Markdown
Contributor

@stack72 stack72 commented May 5, 2026

Summary

Follow-up to swamp-club#237. The legacy swamp data search surface exposed workflowTag and stepTag from data.tags, but not jobTag — leaving the provenance triple incomplete compared to swamp data query (which already supports jobName == \"...\" after #237 wired data.tags.job via workflowTagOverrides).

This PR closes the gap:

  • DataSearchItem gains jobTag?: string, ordered between workflowTag and stepTag to mirror the production tag-write order in execution_service.ts (workflow → job → step).
  • The dataSearch generator populates jobTag: data.tags.job in the result mapping.
  • The Ink renderer surfaces jobTag as a searchable picker token and as a **Job:** line in the preview metadata, between Workflow and Step.

Closes swamp-club#245.

Why no --job filter

data search already has asymmetric filter coverage — --workflow exists, but --step does not. Adding --job would introduce new asymmetry without solving a real ergonomic gap. Power users wanting filter-by-job should use swamp data query 'jobName == \"...\"', which is the documented modern path.

Backward compatibility

Pre-#237 data has no job tag, so jobTag resolves to undefined for those records — identical nullable handling to workflowTag/stepTag on non-workflow data. No migration needed; forward-only.

Test plan

  • deno fmt --check passes
  • deno lint passes
  • deno check passes
  • deno run test — full suite (5403 passed, 0 failed)
  • Positive regression test: when data.tags = { workflow, job, step }, all three *Tag fields are populated together
  • Negative regression test: when data.tags = {}, jobTag === undefined (locks in the nullable contract)

Follow-up

A consolidated swamp-uat issue will be filed alongside this PR covering CLI surfacing of workflowTag/jobTag/stepTag in data search --json (none of the three are exercised at the UAT tier today).

🤖 Generated with Claude Code

…ch (swamp-club#245)

Follow-up to swamp-club#237. After #237, workflow step output carries
`data.tags.job` (populated via `workflowTagOverrides`), but the legacy
`swamp data search` result mapping at src/libswamp/data/search.ts:305-306
exposed only `workflowTag` and `stepTag` — leaving the provenance triple
incomplete on this surface compared to `swamp data query` (which already
supports `jobName == "..."`).

This change fills the gap with three small, additive edits:

- DataSearchItem gains `jobTag?: string`, ordered between workflowTag
  and stepTag to mirror the production tag-write order in
  execution_service.ts (workflow → job → step).
- The dataSearch generator populates `jobTag: data.tags.job`. Pre-#237
  data has no `job` tag, so jobTag becomes `undefined` — same nullable
  handling already used for workflowTag/stepTag.
- The Ink renderer surfaces jobTag both as a searchable picker token
  and as a `**Job:**` line in the preview metadata, between Workflow
  and Step.

Two regression tests cover the wiring: a positive case asserting
workflow/job/step tags are populated together (proves order parity),
and a negative case locking in the `jobTag === undefined` contract
when the source data has no `job` tag.

No `--job` filter added — `data search` already has asymmetric filter
coverage (`--workflow` exists, no `--step`); adding `--job` would
introduce new asymmetry without solving a real ergonomic gap. Power
users should use `swamp data query 'jobName == "..."'`.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Copy link
Copy Markdown

@github-actions github-actions Bot left a comment

Choose a reason for hiding this comment

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

CLI UX Review

Blocking

None.

Suggestions

  1. JSON output — undefined fields: JSON.stringify silently drops jobTag when undefined, so scripts consuming --json output can't distinguish "this record has no job tag" from "this version of swamp doesn't know about jobTag" without reading both jobTag and tags.job. The existing workflowTag/stepTag fields have the same ambiguity, so this isn't a regression — just worth noting if the JSON contract is ever tightened.

Verdict

PASS — focused, consistent addition. jobTag is wired into the fuzzy-search token string, the preview metadata pane (in the correct workflow→job→step order), and flows through the existing JSON serialization path automatically. No new flags, no help-text changes needed.

Copy link
Copy Markdown

@github-actions github-actions Bot left a comment

Choose a reason for hiding this comment

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

Code Review

Clean, well-scoped additive change. No blocking issues.

CLAUDE.md Compliance

  • Import boundary: Renderer imports DataSearchItem from ../../libswamp/mod.ts — correct. Test file imports from internal paths but lives inside src/libswamp/, which is permitted.
  • Test naming: Follows the "functionName: describes behavior" convention.
  • License headers: No new files created; existing files already have headers.
  • No any types: All additions are properly typed (jobTag?: string).

DDD Review

  • DataSearchItem is a Value Object (search result projection) — adding jobTag is consistent with the existing workflowTag/stepTag pattern and mirrors the domain's provenance triple (workflow → job → step).
  • The generator mapping at search.ts:307 is a straightforward projection from the domain's data.tags.job, same pattern as the two siblings.
  • No domain model changes needed — jobTag is already persisted in data.tags by the execution service; this PR just surfaces it.

Test Coverage

  • Positive test: verifies all three tag fields are populated together from data.tags.
  • Negative test: locks in the jobTag === undefined contract when data.tags has no job key.
  • Both tests follow existing patterns and use the established makeDataItem/makeDeps helpers.

Security

  • No user input flows, no injection surfaces. The jobTag value comes from internal data.tags and is rendered via Ink's text components (no raw HTML).

Suggestions

  1. The positive test could also assert that workflowTag and stepTag are undefined in the negative test (alongside jobTag) to fully lock in the nullable contract for all three fields — but the existing tests elsewhere likely cover that, so this is minor.

Looks good to merge.

Copy link
Copy Markdown

@github-actions github-actions Bot left a comment

Choose a reason for hiding this comment

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

Adversarial Review

Critical / High

None.

Medium

None.

Low

  1. src/libswamp/data/search.ts:307Record<string, string> index access typed as string, not string | undefined: data.tags.job is typed as string by TypeScript's Record<string, string>, but at runtime it's undefined when the key is missing. With noUncheckedIndexedAccess enabled this would be flagged. However, this is the pre-existing pattern used identically by workflowTag: data.tags.workflow and stepTag: data.tags.step at lines 306/308, and the receiving field is correctly declared optional (jobTag?: string), so all consumers (nullish coalescing ??, truthiness guard if (item.jobTag)) handle undefined properly. Not a regression from this PR.

Verdict

PASS — Small, additive change that mirrors the existing workflowTag/stepTag pattern exactly. The interface extension is backward-compatible (optional field), the Ink renderer correctly guards against undefined, the JSON renderer needs no changes (serializes e.data directly), and the two regression tests cover both the populated and absent tag cases. No new error paths, no security concerns, no concurrency issues.

@stack72 stack72 merged commit b8bc82b into main May 5, 2026
11 checks passed
@stack72 stack72 deleted the issue-245-data-search-jobtag branch May 5, 2026 12:54
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