Skip to content

fix(#6760): expose work item keys to harness agents - #6769

Merged
ralphbean merged 3 commits into
mainfrom
fix/6760-work-item-key
Aug 31, 2026
Merged

fix(#6760): expose work item keys to harness agents#6769
ralphbean merged 3 commits into
mainfrom
fix/6760-work-item-key

Conversation

@ralphbean

Copy link
Copy Markdown
Member

The common harness-dispatch path currently exports work-item URLs without the matching identifiers, so CEL-triggered code harnesses that require ISSUE_NUMBER fail before the agent starts. This adds the forge-neutral FULLSEND_WORK_ITEM_KEY while keeping the compatibility variable where it is meaningful.

For GitHub issue and PR payloads, both variables carry the numeric identifier. For Jira payloads, FULLSEND_WORK_ITEM_KEY carries event.entity.key and ISSUE_NUMBER stays empty, so we do not invent a relationship to a GitHub issue. The legacy reusable-code and inline route paths now expose the generic key beside their existing issue number too.

Tests pin all three paths, including the Jira distinction.

Closes #6760

Testing: make lint; GOCACHE=/tmp/fullsend-go-cache go test ./internal/scaffold -count=1

Signed-off-by: Ralph Bean <rbean@redhat.com>
@qodo-code-review

Copy link
Copy Markdown

PR Summary by Qodo

Expose work item keys to harness agents

🐞 Bug fix 🧪 Tests 📝 Documentation ⚙️ Configuration changes 🕐 20-40 Minutes

Grey Divider

AI Description

• Exposes forge-neutral work item keys across legacy, routed, and harness dispatch paths.
• Preserves GitHub issue compatibility while keeping Jira keys out of ISSUE_NUMBER.
• Documents and tests provider-specific environment projection behavior.
Diagram

graph TD
  P["Event Payload"] --> E["Context Export"] --> S{"Jira Source?"}
  S -->|Yes| J["Generic Key Only"] --> H["Harness Agent"]
  S -->|No| G["Generic and Issue Keys"] --> H
Loading
High-Level Assessment

Projecting both variables at the shared dispatch boundary is the appropriate approach because agents receive consistent environment semantics without tracker-specific logic. Reusing ISSUE_NUMBER for Jira was correctly rejected because Jira keys do not identify GitHub issues; a broader projection abstraction would add unnecessary scope for this focused compatibility fix.

Files changed (5) +56 / -3

Bug fix (2) +12 / -0
reusable-code.ymlExpose generic keys in legacy code dispatch +1/-0

Expose generic keys in legacy code dispatch

• Adds 'FULLSEND_WORK_ITEM_KEY' to the legacy reusable code-agent environment using the existing GitHub issue number. The compatibility 'ISSUE_NUMBER' remains unchanged.

.github/workflows/reusable-code.yml

reusable-dispatch.ymlProject provider-aware work item keys +11/-0

Project provider-aware work item keys

• Adds the generic key to routed code-agent dispatch and extracts normalized entity keys for the common harness path. GitHub issue and pull request numbers populate both variables, while Jira leaves 'ISSUE_NUMBER' empty and missing keys fail dispatch early.

.github/workflows/reusable-dispatch.yml

Tests (1) +38 / -0
workflow_call_alignment_test.goTest work item environment compatibility +38/-0

Test work item environment compatibility

• Adds workflow assertions for legacy reusable code, routed code, and common harness dispatch paths. Coverage verifies generic key propagation and Jira-specific suppression of 'ISSUE_NUMBER'.

internal/scaffold/workflow_call_alignment_test.go

Documentation (2) +6 / -3
0063-polling-based-work-discovery.mdClarify external tracker issue-number compatibility +2/-1

Clarify external tracker issue-number compatibility

• Documents that 'ISSUE_NUMBER' remains empty when an external tracker key does not represent a GitHub issue.

docs/ADRs/0063-polling-based-work-discovery.md

jira-poll-adapter.mdSpecify Jira work item key projection +4/-2

Specify Jira work item key projection

• Defines Jira projection semantics for 'FULLSEND_WORK_ITEM_KEY' and explicitly excludes Jira keys from 'ISSUE_NUMBER'. It also clarifies equivalent generic and compatibility values for forge-native events.

docs/normative/normalized-event/v1/jira-poll-adapter.md

@github-actions

github-actions Bot commented Aug 29, 2026

Copy link
Copy Markdown

Site preview

Preview: https://f3ee9287-site.fullsend-ai.workers.dev

Commit: 9d35afa4b3d6718ebe855494ecb24e1d1e424dfd

@fullsend-ai-review

fullsend-ai-review Bot commented Aug 29, 2026

Copy link
Copy Markdown

🤖 Review · ⚠️ Cancelled · Started 8:22 PM UTC · Ended 8:23 PM UTC

Commit: aee1aab · View workflow run →

Signed-off-by: Ralph Bean <rbean@redhat.com>
@fullsend-ai-review

fullsend-ai-review Bot commented Aug 29, 2026

Copy link
Copy Markdown

🤖 Finished Review · ✅ Success · Started 8:24 PM UTC · Completed 8:44 PM UTC

Commit: 0c326a1 · View workflow run →

Runtime: claude · Model: opus → claude-opus-4-6 · Effort: high · Cost: $7.27

@codecov

codecov Bot commented Aug 29, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

@qodo-code-review

qodo-code-review Bot commented Aug 29, 2026

Copy link
Copy Markdown

Code Review by Qodo

🐞 Bugs (1) 📘 Rule violations (0) 📜 Skill insights (1)

Grey Divider


Action required

1. GitLab IDs become issue numbers 🐞 Bug ≡ Correctness
Description
The new expression clears ISSUE_NUMBER only for Jira, so a normalized GitLab event exports its
projected GitLab entity ID as if it were a GitHub issue number. Harness scripts that treat this
compatibility variable as GitHub-specific can consequently address an unrelated GitHub issue with
the same number.
Code

.github/workflows/reusable-dispatch.yml[1763]

+          ISSUE_NUMBER=$(printf '%s' "${EVENT_PAYLOAD}" | jq -r 'if ._normalized_event.source.system == "jira" then empty else (.issue.number // .pull_request.number // empty) end')
Relevance

●●● Strong

Recent workflow precedents accept concrete correctness fixes; this deterministic tracker-specific ID
leak conflicts with the PR’s stated compatibility intent.

PR-#6611
PR-#6455

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
The reusable workflow accepts precomputed matrices from custom pollers, including the documented
GitLab polling path. Execution-ref projection places every normalized work-item ID into
issue.number, while the changed condition excludes only Jira; this conflicts with the repository's
statement that ISSUE_NUMBER stays empty for external trackers whose keys do not identify GitHub
issues.

.github/workflows/reusable-dispatch.yml[11-15]
.github/workflows/reusable-dispatch.yml[1623-1627]
internal/harnessdispatch/project.go[54-65]
docs/ADRs/0067-gitlab-cron-polling-event-dispatch.md[184-192]
docs/ADRs/0063-polling-based-work-discovery.md[407-424]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
`ISSUE_NUMBER` is GitHub-specific, but the current expression populates it for every normalized source except Jira. This exposes GitLab entity IDs as GitHub issue numbers.

## Issue Context
Precomputed matrices from supported custom pollers can contain normalized GitLab events, and execution-ref projection copies their numeric entity IDs into the compatibility-shaped `issue.number` or `pull_request.number` fields. Populate `ISSUE_NUMBER` only when the event is GitHub-originated; preserve the appropriate behavior for legacy payloads that have no embedded normalized event.

## Fix Focus Areas
- .github/workflows/reusable-dispatch.yml[1758-1771]
- internal/scaffold/workflow_call_alignment_test.go[835-847]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


2. ADR 0063 decision rewritten 📜 Skill insight ≡ Correctness
Description
The PR adds a new environment-variable behavior contract directly to the Decision section of an
already Accepted ADR. Accepted ADRs may receive annotations and links, but substantive
implementation requirements must be documented outside the historical decision record.
Code

docs/ADRs/0063-polling-based-work-discovery.md[R423-424]

+`entity` maps to a GitHub issue for backward compatibility. `ISSUE_NUMBER`
+remains empty for external trackers whose keys do not identify GitHub issues.
Relevance

●●● Strong

Recent ADR precedents explicitly accept reverting substantive changes to already Accepted ADRs and
moving new requirements elsewhere.

PR-#5244
PR-#2465

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
ADR 0063 is marked Accepted, and the changed lines introduce the new normative rule that
ISSUE_NUMBER remains empty for external trackers. This is a substantive change within its Decision
section rather than an allowed status update, cross-reference, connecting note, or typo fix.

Rule 1062057: Restrict modifications to accepted ADRs on main
docs/ADRs/0063-polling-based-work-discovery.md[1-24]
docs/ADRs/0063-polling-based-work-discovery.md[99-424]
Skill: writing-adrs

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
The change adds the new `ISSUE_NUMBER` behavior directly to the Decision section of Accepted ADR 0063, rewriting the historical decision record.

## Issue Context
The Jira projection contract is already documented in `docs/normative/normalized-event/v1/jira-poll-adapter.md`. Keep the accepted ADR unchanged, or replace the new behavioral statement only with a brief cross-reference to the normative specification if an additional pointer is necessary.

## Fix Focus Areas
- docs/ADRs/0063-polling-based-work-discovery.md[423-424]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


Grey Divider

Context sources
✅ Compliance rules (platform): 62 rules
Review mode: ⚖️ Balanced

Grey Divider

Tip of the day
💡 Did you know, you can type 'qodo, fix this' on a finding and the fix lands right on your PR

More tips ↗ | Customize Qodo ↗ | Qodo docs ↗

Grey Divider

Qodo Logo

Comment thread docs/ADRs/0063-polling-based-work-discovery.md
Comment thread .github/workflows/reusable-dispatch.yml
@fullsend-ai-review fullsend-ai-review Bot added the risk/moderate PR risk: moderate label Aug 29, 2026
@fullsend-ai-review

fullsend-ai-review Bot commented Aug 29, 2026

Copy link
Copy Markdown

Risk Assessment: moderate (2/5)

Details

Small, well-scoped additive change exposing a new env var (FULLSEND_WORK_ITEM_KEY) with matching test and doc updates. Touching high-churn protected CI workflow files elevates Tier 2, but the purely additive nature and tight issue-to-PR scope alignment keep practical risk moderate.

Previous run

Risk Assessment: moderate (2/5)

Details

Small, well-scoped additive change exposing a new env var with matching test and doc updates; elevated only slightly by touching high-churn protected CI workflow files with many recent contributors and fix commits.

@fullsend-ai-review

fullsend-ai-review Bot commented Aug 29, 2026

Copy link
Copy Markdown

Review

Findings

Medium

  • [protected-path] .github/workflows/reusable-code.yml, .github/workflows/reusable-dispatch.yml — This PR modifies files under the .github/ protected path. The PR links to issue Expose FULLSEND_WORK_ITEM_KEY alongside ISSUE_NUMBER #6760 and the description explains the rationale (exposing FULLSEND_WORK_ITEM_KEY to fix failing CEL-triggered harness dispatch). Human approval is always required for protected-path changes, regardless of context.

Low

  • [GHA-workflow-command-injection] .github/workflows/reusable-dispatch.yml:1772 — The issue_number step output is written to GITHUB_OUTPUT using the single-line echo "issue_number=${ISSUE_NUMBER}" format, while the adjacent issue_url and work_item_key outputs use a heredoc delimiter for defense-in-depth. Although ISSUE_NUMBER originates from .issue.number or .pull_request.number (GitHub API integers) or is empty (Jira path), the heredoc pattern should be used for consistency with the other outputs in the same block.
    Remediation: Use the heredoc delimiter pattern (matching issue_url and work_item_key) for issue_number.

  • [edge-case] .github/workflows/reusable-dispatch.yml:1755 — The URL extraction (jq -r '.issue.html_url // .pull_request.html_url // empty') runs before the new WORK_ITEM_KEY extraction. If the event_payload has a valid _normalized_event.entity.key but no .issue.html_url or .pull_request.html_url, the step exits at the URL-is-empty guard before reaching the new code. This is pre-existing behavior and safe today because the normalization projection always synthesizes event_payload.issue.html_url from entity.url.

  • [output-delimiter-hygiene] .github/workflows/reusable-dispatch.yml:1760 — The same DELIM value is reused as the heredoc delimiter for both issue_url and work_item_key outputs. While functionally correct (GitHub Actions parses each <<DELIM / DELIM pair independently), the ISSUE_URL_ prefix is now misleading since it also guards work_item_key.

  • [env-var-coverage-consistency] .github/workflows/reusable-dispatch.ymlFULLSEND_WORK_ITEM_KEY is added to the code and harness agent steps but not to triage, review, or prioritize, even though all three already set FULLSEND_WORK_ITEM_URL. This follows the existing pattern — ISSUE_NUMBER is also absent from those steps — so the asymmetry is pre-existing rather than introduced by this PR.


Next steps:

  • /fs-fix — agent addresses review findings automatically
  • /fs-fix <your instruction> — agent fixes with your specific guidance
  • Push commits directly — review re-runs automatically on push
  • /fs-fix-stop — disable automatic fix runs for this PR
Previous run

Review

Findings

Medium

  • [protected-path] .github/workflows/reusable-code.yml, .github/workflows/reusable-dispatch.yml — This PR modifies files under the .github/ protected path. The PR links to issue Expose FULLSEND_WORK_ITEM_KEY alongside ISSUE_NUMBER #6760 and the description explains the rationale (exposing FULLSEND_WORK_ITEM_KEY to fix failing CEL-triggered harness dispatch). Human approval is always required for protected-path changes, regardless of context.

Low

  • [GHA-workflow-command-injection] .github/workflows/reusable-dispatch.yml:1770 — The work_item_key step output is written to GITHUB_OUTPUT using the single-line echo "work_item_key=${WORK_ITEM_KEY}" format, while the adjacent issue_url output uses a heredoc delimiter for defense-in-depth. Since WORK_ITEM_KEY can originate from ._normalized_event.entity.key (a string like PROJ-123, not a guaranteed integer), the heredoc pattern should be used for consistency. Risk is mitigated by upstream schema validation and trusted dispatch infrastructure.
    Remediation: Use the heredoc delimiter pattern (matching issue_url) for work_item_key.

  • [env-var-coverage-consistency] .github/workflows/reusable-dispatch.ymlFULLSEND_WORK_ITEM_KEY is added to the code and harness agent steps but not to triage, review, or prioritize, even though all three already set FULLSEND_WORK_ITEM_URL. This follows the existing pattern — ISSUE_NUMBER is also absent from those steps — so the asymmetry is pre-existing rather than introduced by this PR. See also: [scope-completeness] finding at this location.


Next steps:

  • /fs-fix — agent addresses review findings automatically
  • /fs-fix <your instruction> — agent fixes with your specific guidance
  • Push commits directly — review re-runs automatically on push
  • /fs-fix-stop — disable automatic fix runs for this PR

fullsend-ai-review[bot]

This comment was marked as outdated.

fullsend-ai-review[bot]

This comment was marked as outdated.

Signed-off-by: Ralph Bean <rbean@redhat.com>
@fullsend-ai-review

fullsend-ai-review Bot commented Aug 30, 2026

Copy link
Copy Markdown

🤖 Finished Review · ✅ Success · Started 2:46 PM UTC · Completed 3:08 PM UTC

Commit: 9d35afa · View workflow run →

Runtime: claude · Model: opus → claude-opus-4-6 · Effort: high

@fullsend-ai-review fullsend-ai-review Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

See the review comment for full details.

Comment thread .github/workflows/reusable-dispatch.yml
Comment thread .github/workflows/reusable-dispatch.yml
Comment thread .github/workflows/reusable-dispatch.yml
@ralphbean
ralphbean added this pull request to the merge queue Aug 31, 2026
Merged via the queue into main with commit 8bf8b1f Aug 31, 2026
52 checks passed
@ralphbean
ralphbean deleted the fix/6760-work-item-key branch August 31, 2026 15:23
@fullsend-ai-retro

fullsend-ai-retro Bot commented Aug 31, 2026

Copy link
Copy Markdown

🤖 Finished Retro · ✅ Success · Started 3:25 PM UTC · Completed 3:36 PM UTC

Commit: 9d35afa · View workflow run →

Runtime: claude · Model: opus → claude-opus-4-6 · Effort: high · Cost: $3.73

@fullsend-ai-retro

Copy link
Copy Markdown

Retro: PR #6769 — expose work item keys to harness agents

Workflow shape: Human-authored PR (ralphbean) fixing #6760. Two review agent passes, one human approval, merge. No code/triage/fix agents involved.

Timeline:

  1. Aug 29 20:20 — PR opened (3 commits, 5 files, +65/−3). Adds FULLSEND_WORK_ITEM_KEY env var alongside ISSUE_NUMBER for forge-neutral work item identification, with Jira-specific handling.
  2. Aug 29 20:23–20:44 — First review (run 33273340273): opus, $7.27, 226 tool calls, 20 min. Found 3 findings including an actionable GHA-workflow-command-injection issue (work_item_key using single-line echo instead of heredoc). Verdict: request-changes.
  3. Aug 30 14:44 — Author pushed fix (commit 9d35afa): converted work_item_key output to heredoc format and added regression test.
  4. Aug 30 14:45–15:09 — Second review (run 33317698843): opus, 127 tool calls, 24 min. Correctly recognized the work_item_key fix and shifted the injection finding to issue_number (still single-line echo). Found 5 findings total (all Low except protected-path Medium). Verdict: request-changes. Suffered model availability failures (sonnet unavailable on Vertex, 3+ sub-agent retries) and a metrics anomaly (exit_code=-1, num_turns=0, cost=$0.00 despite valid output).
  5. Aug 31 06:38 — Human reviewer (rh-hemartin) approved.
  6. Aug 31 15:24 — Merged by ralphbean.

What went well:

  • The review agent caught a real security hygiene issue (heredoc pattern for GHA output) and the author fixed it.
  • The re-review correctly tracked the fix and identified the remaining instance (issue_number).
  • Both reviews reached consistent risk assessments (2/5 moderate).
  • All CI checks passed; codecov confirmed 100% patch coverage.

Existing issues corroborated by this retro (not filed as new proposals):

Proposals filed

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

risk/moderate PR risk: moderate

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Expose FULLSEND_WORK_ITEM_KEY alongside ISSUE_NUMBER

2 participants