feat(#1074): add Jira-source overlay to code harness - #1075
feat(#1074): add Jira-source overlay to code harness#1075fullsend-ai-coder[bot] wants to merge 11 commits into
Conversation
Replace the deprecated forge: block in harness/code.yaml with overlays: entries using CEL when: expressions. Add a Jira-source overlay guarded by event.source.system == "jira" that: - overrides pre_script with a Jira-aware pre-code-jira.sh that fetches the issue via fullsend issues get --tracker jira, validates the Jira URL and credentials, and writes the issue context to /tmp/jira-issue-context.json - copies the context file into the sandbox at /sandbox/workspace/.issue-context.json via host_files, keeping Jira credentials on the runner only - sets FULLSEND_SOURCE_TRACKER=jira in the sandbox so the agent knows to read the prepared context file Post-script selection remains based on runtime.forge so GitHub targets still push via GitHub and GitLab targets via GitLab. Both the Jira-source and target-forge overlays match and merge for a Jira-triggered run. Update the code-implementation skill to check for FULLSEND_SOURCE_TRACKER=jira and read .issue-context.json instead of calling gh issue view or the GitLab API. Add pre-code-jira-test.sh covering URL validation, credential checks, context file creation, and error paths for both Jira->GitHub and Jira->GitLab compositions. Closes #1074
|
🤖 Finished Review · ✅ Success · Started 10:11 PM UTC · Completed 10:53 PM UTC Commit: Runtime: claude · Model: opus → claude-opus-4-6 · Effort: high |
|
Risk Assessment: elevated (3/5) DetailsLarge blast radius (5), 11 protected path changes (5), and CI workflow modification (4) drive Tier 1 to 2.63; high churn (4), multi-author contention (5), and heavy fix/revert history (5) in Tier 2 produce 3.14; Tier 3 remains low (1.67) as this is an additive-only Jira overlay with clear issue scope, yielding a weighted composite of 2.59 that rounds to 3 (elevated), consistent with the prior assessment. Previous runRisk Assessment: elevated (3/5) DetailsLarge blast radius (5), 11 protected path changes (5), and CI workflow modification (4) drive Tier 1 up, while high churn (4) and multi-author contention (5) in Tier 2 reinforce elevated risk; Tier 3 is low (1.83) due to additive-only overlay with clear issue scope, but preserving prior score of 3 as Tier 1 signals are unchanged and Tier 2 high-signal dimensions support elevated level. Previous run (2)Risk Assessment: elevated (3/5) DetailsAnchored to prior score of 3. Tier 1 signals unchanged: large blast radius (5), 11 protected path changes (5), and CI workflow modification (4) drive risk up, offset by bot authorship (1), no security-sensitive files (1), and no dependency changes (1). Only 3 files changed since prior review — all documentation and configuration updates. Tier 2 churn and multi-author contention signals remain consistent. Tier 3: well-specified linked issue with clear acceptance criteria and CEL-guarded activation reduces deployment risk. Previous run (3)Risk Assessment: elevated (3/5) DetailsAnchored to prior score of 3. Tier 1 signals unchanged: large blast radius (5), 11 protected path changes (5), and CI workflow modification (4) drive risk up, offset by bot authorship (1), no security-sensitive files (1), and no dependency changes (1). Tier 2 confirms high churn and multi-author contention across existing files. Bulk of change is new Jira-source scripts, limiting regression risk. Tier 3: well-specified issue with clear acceptance criteria and CEL-guarded activation reduces deployment risk. Previous run (4)Risk Assessment: elevated (3/5) DetailsAnchored to prior score of 3. Tier 1 signals unchanged: large blast radius (5), 5 protected path changes (5), and CI workflow modification (4) drive risk up, offset by bot authorship (1), no security-sensitive files (1), and no dependency changes (1). Tier 2 shows high churn and multi-author contention across existing files. Bulk of change is new scripts, limiting regression risk. Tier 3: well-specified issue with clear acceptance criteria reduces ambiguity. Previous run (5)Risk Assessment: elevated (3/5) DetailsAnchored to prior score of 3. Tier 1 signals unchanged: large blast radius (5), 5 protected path changes (5), and CI workflow modification (4) drive risk up, offset by bot authorship, no security-sensitive files, and no dependency changes. High churn on harness/code.yaml and SKILL.md (Tier 2) adds historical risk, but the bulk of the change is new scripts. Well-specified issue with clear acceptance criteria (Tier 3) reduces ambiguity. Previous run (6)Risk Assessment: elevated (3/5) DetailsAnchored to prior score of 3. Tier 1 signals unchanged: large blast radius (5), 5 protected path changes (5), and CI workflow modification (4) drive risk up, offset by bot authorship, no security-sensitive files, and no dependency changes. Tier 2 confirms high churn and multi-author contention on existing files. Good issue alignment and largely additive change sustain the prior elevated assessment. Previous run (7)Risk Assessment: elevated (3/5) DetailsTier 1 signals unchanged from prior assessment — large blast radius with 5 protected path changes and CI workflow modifications drive risk up, while high churn and multi-author contention on existing files elevate Tier 2, but the change is largely additive new scripts by a bot with clear issue alignment and no security-sensitive changes, sustaining the prior elevated score. Previous run (8)Risk Assessment: elevated (3/5) DetailsLarge blast radius with 5 protected path changes and CI workflow modifications drive Tier 1 up, while high churn and multi-author contention on existing files elevate Tier 2, but the change is largely additive new scripts by a bot with clear issue alignment. |
ReviewFindingsHigh
Medium
Low
Next steps:
Previous runReviewFindingsMedium
Low
Next steps:
Previous run (2)ReviewFindingsMedium
Low
Next steps:
Previous run (3)ReviewFindingsMedium
Low
Next steps:
Previous run (4)ReviewFindingsMedium
Low
Previous run (5)ReviewFindingsMedium
Low
Previous run (6)ReviewFindingsMedium
Low
Next steps:
Previous run (7)ReviewFindingsMedium
Low
Previous run (8)ReviewFindingsHigh
Medium
Low
Next steps:
|
|
🤖 Finished Fix · ✅ Success · Started 10:55 PM UTC · Completed 11:04 PM UTC Commit: Runtime: claude · Model: opus → claude-opus-4-6 · Effort: high · Cost: $3.57 |
- Update docs/code.md: Multi-forge section now describes overlays with CEL when: expressions instead of stale forge.<platform> references; FULLSEND_FORGE description references overlay env section; add FULLSEND_SOURCE_TRACKER to Variables table; document Jira-source overlay - Document intentional omission of existing-PR check in Jira pre-script (forge_list_prs_for_issue searches for #N closing keywords which do not apply to Jira issue keys) - Add ISSUE_NUMBER to Jira overlay sandbox env block (explicit dependency instead of relying on forge overlay merge) - Fix empty-issue-context test to actually exercise the empty-file guard (previously exited at CLI-failure branch before reaching -s check) - Correct JIRA_BASE_URL documentation: optional, not required - Add emoji prefix to Jira notice annotation for consistency - Clarify SKILL.md ISSUE_NUMBER wording for Jira flow Addresses review feedback on #1075
🔧 Fix agent — iteration 1 (bot-triggered)Addressed 9 of 13 review findings: updated stale documentation in docs/code.md (Multi-forge section, FULLSEND_FORGE description, added FULLSEND_SOURCE_TRACKER), documented intentional omission of existing-PR check for Jira flows, added ISSUE_NUMBER to Jira overlay sandbox env, fixed empty-context test coverage, corrected JIRA_BASE_URL documentation accuracy, added emoji prefix for naming consistency, and clarified SKILL.md wording. Disagreed with 4 findings: code-duplication (better as follow-up), code-organization (already documented), error-handling-idiom (style preference), and protected-path (informational). Fixed (9):
Disagreed (4):
Tests: passedNext steps:
|
|
🤖 Finished Review · ✅ Success · Started 11:06 PM UTC · Completed 11:48 PM UTC Commit: Runtime: claude · Model: opus → claude-opus-4-6 · Effort: high |
Superseded by updated review
|
/fs-fix why FULLSEND_SOURCE_TRACKER and not FULLSEND_TRACKER (like triage)? |
|
🤖 Finished Fix · ✅ Success · Started 2:28 AM UTC · Completed 2:34 AM UTC Commit: Runtime: claude · Model: opus → claude-opus-4-6 · Effort: high · Cost: $2.12 |
Align the Jira-source overlay env var with the established triage convention (FULLSEND_TRACKER) instead of inventing a new name. Addresses review feedback on #1075
🔧 Fix agent — iteration 2 (human-triggered)Renamed FULLSEND_SOURCE_TRACKER to FULLSEND_TRACKER across all 3 files (harness/code.yaml, skills/code-implementation/SKILL.md, docs/code.md) to align with the established triage harness convention. All pre-code-jira tests (12/12) and pre-code tests (33/33) pass. Fixed (3):
Tests: passedNext steps:
|
|
🤖 Finished Review · ✅ Success · Started 2:36 AM UTC · Completed 2:56 AM UTC Commit: Runtime: claude · Model: opus → claude-opus-4-6 · Effort: high · Cost: $9.07 |
|
🤖 Finished Fix · ✅ Success · Started 2:58 AM UTC · Completed 3:06 AM UTC Commit: Runtime: claude · Model: opus → claude-opus-4-6 · Effort: high · Cost: $2.83 |
- Reorder Jira overlay after forge overlays in harness/code.yaml to fix ISSUE_URL env variable conflict under last-writer-wins merge semantics - Sanitize ISSUE_URL and JIRA_BASE_URL in GHA ::error:: workflow commands to prevent command injection via embedded newlines - Add warning log in SKILL.md when FULLSEND_TRACKER=jira but context file is missing, instead of silently falling through to forge APIs - Add "Testing code agent with Jira" section to LOCAL.md Addresses review feedback on #1075
🔧 Fix agent — iteration 3 (bot-triggered)Addressed 5 of 8 review findings. Fixed the medium-severity ISSUE_URL env variable conflict by reordering the Jira overlay after forge overlays. Hardened two GHA workflow command echo sites against injection. Added missing-file warning in SKILL.md and local testing docs. Disagreed with 3 findings: protected-path (informational), edge-case (documented intentional), code-duplication (out of scope). Fixed (5):
Disagreed (3):
Tests: passed
Decision points
Next steps:
|
|
🤖 Finished Review · ✅ Success · Started 3:08 AM UTC · Completed 3:50 AM UTC Commit: Runtime: claude · Model: opus → claude-opus-4-6 · Effort: high |
Superseded by updated review
|
🤖 Finished Review · ✅ Success · Started 11:49 AM UTC · Completed 12:27 PM UTC Commit: Runtime: claude · Model: opus → claude-opus-4-6 · Effort: high · Cost: $7.56 |
|
🤖 Review · Commit: |
|
🤖 Review · Commit: |
|
🤖 Finished Review · ✅ Success · Started 6:52 PM UTC · Completed 7:13 PM UTC Commit: Runtime: claude · Model: opus → claude-opus-4-6 · Effort: high · Cost: $12.21 |
|
🤖 Finished Fix · ❌ Failure (post-script /home/runner/work/agents/agents/.fullsend/.fullsend-cache/resources/sha256/e14f2eff53cc1ed5cb9200bf5471721ee531c61b6314e8977d603eae321214cd/scripts/post-fix.sh failed: exit status 1) · Started 7:15 PM UTC · Completed 7:32 PM UTC Commit: Runtime: claude · Model: opus → claude-opus-4-6 · Effort: high · Cost: $5.62 |
|
The fix agent completed, but the post-fix script failed before finishing. Workflow run: https://github.com/fullsend-ai/agents/actions/runs/33270303619 Details: |
|
🤖 Finished Review · ✅ Success · Started 7:43 PM UTC · Completed 8:02 PM UTC Commit: Runtime: claude · Model: opus → claude-opus-4-6 · Effort: high · Cost: $10.10 |
|
🤖 Finished Fix · ✅ Success · Started 8:04 PM UTC · Completed 8:14 PM UTC Commit: Runtime: claude · Model: opus → claude-opus-4-6 · Effort: high · Cost: $3.65 |
- Restore CODE_ALLOWED_TARGET_BRANCHES passthrough in top-level env.runner (env-var-contract-violation) - Replace FULLSEND_WORK_ITEM_URL with ISSUE_URL in SKILL.md — the sandbox only receives ISSUE_URL via the harness mapping (logic-error) - Use grep -qwF for cross-work-item ownership check to prevent substring false positives e.g. PROJ-1 matching PROJ-12 (injection-check-weakening) - Rename _sanitize_gha to _gha_sanitize and add ANSI-escape strip to match canonical definition (naming-inconsistency) - Apply _gha_sanitize to ::notice:: interpolation for defense-in-depth (GHA-workflow-command-injection) - Add REPO_FULL_NAME :? guard in pre-code-jira.src.sh (missing-validation) - Remove ISSUE_REF_KEYWORD intermediary to match test helper pattern (style-inconsistency) Addresses review feedback on #1075
🔧 Fix agent — iteration 4 (bot-triggered)Addressed 7 of 10 review findings. Fixed: CODE_ALLOWED_TARGET_BRANCHES passthrough restoration, SKILL.md variable reference correction (FULLSEND_WORK_ITEM_URL to ISSUE_URL), cross-work-item injection substring match hardening, _sanitize_gha to _gha_sanitize rename with ANSI strip, GHA workflow command injection defense-in-depth, REPO_FULL_NAME validation guard, and ISSUE_REF_KEYWORD style inconsistency. Disagreed with 3: protected-path (informational), code-duplication (out of PR scope), edge-case (intentionally documented). Fixed (7):
Disagreed (3):
Tests: passedNext steps:
|
|
🤖 Finished Review · ✅ Success · Started 8:16 PM UTC · Completed 8:36 PM UTC Commit: Runtime: claude · Model: opus → claude-opus-4-6 · Effort: high · Cost: $8.72 |
|
🤖 Finished Fix · ✅ Success · Started 8:38 PM UTC · Completed 8:46 PM UTC Commit: Runtime: claude · Model: opus → claude-opus-4-6 · Effort: high · Cost: $2.32 |
docs/code.md described the code agent deriving the work-item key from FULLSEND_WORK_ITEM_URL, but that variable is runner-only — the Jira overlay maps it to ISSUE_URL in env.sandbox. The prior iteration fixed SKILL.md; this fixes the remaining reference in the design doc. Addresses review feedback on #1075
🔧 Fix agent — iteration 5 (bot-triggered)Fixed the last remaining FULLSEND_WORK_ITEM_URL reference in sandbox-agent documentation (docs/code.md). SKILL.md was already corrected in prior iterations. The docs now consistently use ISSUE_URL, matching the harness overlay's env.sandbox mapping. Fixed (1):
Tests: passed
Decision points
Next steps:
|
|
🤖 Finished Review · ✅ Success · Started 8:48 PM UTC · Completed 9:30 PM UTC Commit: Runtime: claude · Model: opus → claude-opus-4-6 · Effort: high |
There was a problem hiding this comment.
Note: The following review comments could not be posted on the diff (GitHub returned 422) and are included here instead:
scripts/post-code.src.sh(file-level): Line 233 · [high] logic-error
Jira+GitLab composition will fail at runtime. When FULLSEND_FORGE=gitlab and event.source.system=jira, the Jira overlay sets ISSUE_URL to the Jira browse URL. The GitLab validation block calls forge_validate_issue_url on ISSUE_URL, which checks against the GitLab URL pattern. The Jira URL will never match, causing exit 1. Additionally, GITLAB_HOST derivation from ISSUE_URL would extract the Jira host instead of the GitLab host, breaking all subsequent GitLab API calls.
Suggested fix: When EXTERNAL_WORK_ITEM=true and FULLSEND_FORGE=gitlab, skip forge_validate_issue_url on ISSUE_URL and derive GITLAB_HOST from CI_SERVER_HOST instead.
| # Auto-detect and install pre-commit tool dependencies | ||
| # --------------------------------------------------------------------------- | ||
| # This section is shared with the forge pre-script — the target repo is | ||
| # the same regardless of whether the source issue is Jira or a forge. |
There was a problem hiding this comment.
[low] code-duplication
Pre-commit tool resolution block (lines 129-183) is a verbatim copy from pre-code.src.sh. The codebase has an established lib/*.lib.sh pattern.
Suggested fix: Extract to scripts/lib/precommit-resolve.lib.sh and source from both scripts.
| echo "::error::Jira issue context is not valid JSON" | ||
| exit 1 | ||
| fi | ||
|
|
There was a problem hiding this comment.
[low] edge-case
The Jira pre-script omits the existing-PR check present in the forge pre-script. Documented as intentional: forge_list_prs_for_issue would produce false negatives for Jira keys (PROJ-42 vs #N).
| if pr_body_refs_issue "${PR_BODY_TEXT}" "${ISSUE_NUMBER}"; then | ||
| if [ "${EXTERNAL_WORK_ITEM}" = "true" ]; then | ||
| if printf '%s\n' "${PR_BODY_TEXT}" | grep -qwF -- "${WORK_ITEM_URL}"; then | ||
| PR_CLOSES_THIS_ISSUE=true |
There was a problem hiding this comment.
[low] Cross-work-item injection check weakening
The external-work-item PR ownership check uses grep -qwF. The -w flag mitigates substring false-positives. Primary defense (branch namespace) remains unaffected.
|
🤖 Finished Fix · ❌ Failure (running pre-script: exit status 1) · Started 9:32 PM UTC · Completed 9:32 PM UTC Commit: Effort: high |
Summary
forge:block tooverlays:with CELwhen:expressions, matching the pattern established in the triage harness (Port triage agent from forge to overlays method #1013)event.source.system == "jira") that fetches issue content viafullsend issues get --tracker jiraon the runner, writes it to a context file, and copies it into the sandbox without exposing Jira credentials.issue-context.jsonwhenFULLSEND_SOURCE_TRACKER=jirainstead of calling forge APIsDesign
The Jira overlay is ordered before the forge overlays so its
pre_scriptoverrides the default forge pre-script. Post-script selection remains based onruntime.forge, so a Jira→GitHub run still pushes and creates a PR through GitHub. Both the Jira-source and target-forge overlays match and merge for a Jira-triggered run (merge-all-matching behavior).Jira credentials (
JIRA_USER_EMAIL,JIRA_TOKEN,JIRA_BASE_URL) are scoped toenv.runneronly — they never enter the sandbox. The sandbox receives the issue content as a JSON file at/sandbox/workspace/.issue-context.jsonand aFULLSEND_SOURCE_TRACKER=jirasignal.Testing
pre-code-jira-test.shwith 12 test cases covering:JIRA_BASE_URLmismatch rejectedfullsendCLI failure handlingpre-code-test.shandpost-code-test.shtests pass unchangedmake check-bundle) passesCloses #1074
Post-script verification
agent/1074-jira-source-code-overlay)20bd058ec31d8cd9a6c34bb9d04b5247b0440fce..HEAD)